Error in install.packages : Updating loaded packages
Error in install.packages : Updating loaded packages
trying URL 'http://cran.us.r-project.org/bin/macosx/contrib/4.0/rgeos_0.5-5.tgz'
Content type 'application/x-gzip' length 8537441 bytes (8.1 MB)
==================================================
downloaded 8.1 MB
The downloaded binary packages are in
/var/folders/gs/080wb67j58df5y8ccjf53yw00000gn/T//RtmpcHXjz6/downloaded_packages
Simple Scattergram
First we are going to try to present this pattern for different tiers of universities (admission rate as well as debt)
# Remove PrivacySuppressed Records and transform Debt Median into a numeric value - we can also do this on the main sc df
sc$DEBT_MDN[is.na(sc$DEBT_MDN)] <- 0;
brewer.pal(n=10,"PuBuGn")
n too large, allowed maximum for palette PuBuGn is 9
Returning the palette you asked for with that many colors
[1] "#FFF7FB" "#ECE2F0" "#D0D1E6" "#A6BDDB" "#67A9CF" "#3690C0" "#02818A" "#016C59" "#014636"
ShortPuBuGn <- c("#D0D1E6","#A6BDDB","#67A9CF","#3690C0","#02818A")
m <- sc %>% subset(DEBT_MDN !='PrivacySuppressed') %>% transform(DEBT_MDN = as.numeric(DEBT_MDN)) %>%
ggplot(., aes(x=ADM_RATE, y=DEBT_MDN,color=uni_rank)) +
geom_point(pch=21) +
geom_smooth(color='navy', se = FALSE) +
scale_color_manual(values=ShortPuBuGn)+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background= element_rect(fill="white")) +
scale_y_discrete(limits=c(0,10000,20000,30000), labels=c('0','10','20','30')) +
labs(x='Admissions Rate', y='Median Loan Amount per Student\n(thousands)',
title='Student Debt and Admissions Rate',
color='Selectivity')
Continuous limits supplied to discrete scale.
Did you mean `limits = factor(...)` or `scale_*_continuous()`?
m

This plot sets out to show the relationship between median loan amount in 2019 and the admissions rate. The trend shown here is that as the admissions rate goes up (i.e., as schools become less selective), so does median loan amount (at least until we go from less selective to not selective). Based on the scatterplot, it can also be seen that the variance goes up in terms of median student loan amount (although it can also be seen that this is partially due to the much larger number of schools in the less selective buckets).
This is somewhat interesting because more exclusive/selective schools are on average viewed as more ‘competitive’ and ‘prestigious’ (e.g., Harvard, Stanford, etc.); a great deal of existent literature has noted that such ‘prestigious’ schools often end up admitting more people from economically privileged backgrounds (outside of those admitted specifically for diversity), as ‘merit-based’ admissions often correlate with access to economic and financial resources, which allow for access to resources helpful for competence signalling, such as standardized test prep courses, sports and activities, etc; furthermore, such schools include more financial resources (as more prestigious schools produce alma maters with higher socioeconomic outcomes) and thus potentially can help more with financial aid and scholarships.
This is a data table showing the breakdown of the university ranks (as I chose to rank them). I will note that from the dt alone wwe are seeing a downward trend in the ‘Median Student Loans’ column.
This data table summarizes how we categorized our variable for university selectivity grouping (from the College Scorecard file). It describes the median student loans and the number of universities in each category as of 2019, as well as the Minimum Acceptance Rate, and the Maximum Acceptance Rate thresholds.
sc_dt %>% dplyr::mutate(Description=paste(`University Selectivity`, '\n',`Number of Universities`,'Universities'), sep ="\n") %>%
treemap(index="Description",
vSize="Number of Universities",
type="index",
fontsize.labels=c(12, 8),
palette = viridis(5),
border.col="white",
title = 'Universities and Selectivity')
the condition has length > 1 and only the first element will be used

The treemap above visualizes and summarizes the selectivity grouping label and university counts within each of the categorical selectivity groupings. As shown above, the vast majority of schools in our dataset were ‘not selective’ or ‘less selective’; however, many of our analyses focus on the smaller categories (particularly selective to highly selective/elite), because these categories have more within-group homogeneity and furthermore are more interesting to our focal questions.
Scattergram as Violin Plot
m <- sc %>% subset(DEBT_MDN !='PrivacySuppressed') %>% transform(DEBT_MDN = as.numeric(DEBT_MDN)) %>%
ggplot(., aes(x=uni_rank, y=DEBT_MDN)) +
geom_violin(aes(fill=uni_rank,color=uni_rank)) +
geom_boxplot(width = 0.2)+
scale_fill_manual(values=ShortPuBuGn) +
scale_colour_manual(values=ShortPuBuGn) +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background= element_rect(fill="white"))+
scale_y_discrete(limits=c(0,10000,20000,30000), labels=c('0','10','20','30')) +
scale_x_discrete(labels=c('not\nselective\n(>70%)','less\nselective\n(50%-70%)',
'selective\n(30%-50%)','more\nselective\n(20%-30%)','highly\nselective\n(5%-20%)','elite\n(<5%)')) +
labs(x='Selectivity\n(admission rate thresholds)', y='Median Loan Amount per Student\n(thousands)',
title='Selective Schools and Student Debt',
color='',fill='')
m
Showing the previous scattergram specifically as violin plots
ipeds15 <- get_education_data(level = "college-university",
source = "ipeds",
topic = "grad-rates-pell",
filters = list(year = 2015))
ipeds15
Student Debt over Time
#Process the data
sc_time <- read_csv('2010_2019_student_debt.csv')
sc_time<- sc_time %>% subset(DEBT_MDN !='PrivacySuppressed') %>%
transform(DEBT_MDN = as.numeric(DEBT_MDN)) %>%
dplyr::mutate(DEBT_MDN = ifelse(is.na(DEBT_MDN), 0, DEBT_MDN))
sum(sc_time$UGDS,na.rm=TRUE)
[1] 90801007
Below is an interactive line graph (2010-2019) which details the trends in student debt over the years.
Between 2010 and 2018, the median loan amount per student increased by 2000-4000+ USD (inflation-adjusted) - nationally, the median student loan amount increased by 19%. When one disaggregates universities by selectivity, we see the same overall trend over time (i.e., there is a fair amount of increase during the period in terms of average student loans that students leave with upon entering repayment); however, some selectivity groups increased more dramatically than others (e.g., ‘More Selective’ or schools with 20-30% acceptance rates appeared to increase greatly in terms of student debt principal between 2015 and 2017, but this amount declined a bit again in 2018) and different selectivity groups decreased in median student debt over time (less selective; selective schools seemed to decrease in median debt following 2014).
To look at how median student debt has changed either by only national average or to look at specific ‘selectivity’ buckets, one can simply click to remove the remaining lines in the plot.
The following is (instead) a bar graph with fewer ‘university selectivity’ buckets.
sc_time_df <- sc_time %>% group_by(`Year_Ending`) %>% mutate(`Average Annual Student Debt - National` = sum(DEBT_MDN_STUDENT,na.rm=TRUE)/sum(UGDS,na.rm=TRUE)) %>% ungroup() %>%
dplyr::mutate(uni_rank = case_when(
ADM_RATE < 0.2 ~ 'highly selective',
ADM_RATE < 0.5 ~ 'moderately selective',
TRUE ~ 'less/not at all selective')) %>%
mutate(uni_rank = factor(uni_rank, levels=c('less/not at all selective', 'moderately selective', 'highly selective'))) %>%
group_by(uni_rank,Year_Ending) %>%
mutate(`Average Annual Student Debt (by Selectivity)` = sum(DEBT_MDN_STUDENT,na.rm=TRUE)/sum(UGDS,na.rm=TRUE)) %>%
ungroup() %>%
group_by(`Year_Ending`,`Average Annual Student Debt (by Selectivity)`,
uni_rank,`Average Annual Student Debt - National`) %>% summarize() %>%
merge(cf) %>%
mutate(`Adjusted Average Annual Student Debt` = `Average Annual Student Debt (by Selectivity)`/
CPIAUCSL) %>%
mutate(`Adjusted Average Annual Student Debt - Composite` = `Average Annual Student Debt - National`/
CPIAUCSL)
sc_df <- sc_time_df %>% group_by(`Average Annual Student Debt - National`,`Adjusted Average Annual Student Debt - Composite`,Year_Ending) %>% summarize() %>% mutate(uni_rank='national average') %>% mutate(`Adjusted Average Annual Student Debt`=`Adjusted Average Annual Student Debt - Composite`) %>% dplyr::mutate(`Average Annual Student Debt (by Selectivity)` = `Average Annual Student Debt - National`) %>% merge(cf) %>% select(Year_Ending,`Average Annual Student Debt (by Selectivity)`, uni_rank, `Average Annual Student Debt - National`, CPIAUCSL, `Adjusted Average Annual Student Debt`,`Adjusted Average Annual Student Debt - Composite`)
sc_time_df <- sc_time_df %>% rbind(sc_df) %>% mutate(uni_rank = factor(uni_rank, levels=c('national average','less/not at all selective', 'moderately selective', 'highly selective')))
fig1 <- sc_time_df %>% plot_ly(x = ~Year_Ending, y = ~`Adjusted Average Annual Student Debt`, type = 'bar',
color = ~uni_rank, alpha=0.8, hovertemplate = 'Average Debt/Student (USD): %{y} <extra></extra>',colors='Purples') %>%
layout(yaxis = list(
title = "Average Annual Student Debt per Student\n(Adjusted for Inflation)"))
fig1
Chloropleth showing average student debt (this is only 2019 but I have a filter at the beginning that will allow me to incorporate a slider for the year).
<<<<<<< Updated upstream
# Additions of States df from Tigris File
library(tigris)
=======
# Additions of States df from Tigris File
library(tigris)
>>>>>>> Stashed changes
states <- states(cb = TRUE)
# Can change to sc_time_year
sc_time_2019 <- sc_time %>% subset(Year_Ending = 2019) %>%
group_by(STABBR) %>% mutate(`Average Student Loans`=sum(DEBT_MDN_STUDENT,na.rm=TRUE)/sum(UGDS,na.rm=TRUE)) %>% group_by(STABBR,`Average Student Loans`) %>% summarize()
# States
states_2019 <- states %>%
inner_join(sc_time_2019, by=c(STUSPS='STABBR'))
library(leaflet.providers)
library(leaflet)
#used 'success' measures.
pal = colorFactor('Greens', domain = states_2019$`Average Student Loans`)
pop_pop <- paste("State:",states_2019$NAME,"<br/>",
"Average Student Loans","<br/>",
"of Schools Located in State:",paste('$',round(states_2019$`Average Student Loans`)))
library(htmlwidgets)
library(htmltools)
states_2019_title <- tags$p(tags$style('p{color:gray; font-size: 14px; family: serif}'),
tags$b('Average Debt By State (2019)'))
leaflet(states_2019) %>% addProviderTiles("CartoDB.Positron") %>%
addPolygons(fillColor = ~pal(states_2019$`Average Student Loans`),
color = "white",
weight = 0.5,
fillOpacity = 0.7,
highlight = highlightOptions(
weight = 5,
color = "#666",
fillOpacity = 0.7,
bringToFront = TRUE,
),popup=pop_pop) %>% addLegend(position = "bottomleft", colors =c("#EDF8E9","#BAE4B3","#74C476","#31A354","#006D2C"),
labels = c(paste('$',round(min(states_2019$`Average Student Loans`)))," "," "," ",
paste('$',round(max(states_2019$`Average Student Loans`)))),
title = "Average Student Loans (Per Student)") %>%
leaflet::setView(-98.5795, 39.8282, zoom=3) %>% addControl(states_2019_title, position='topright')
?addLegend
brewer.pal(n = 8, name = "RdYlGn")
# last edit to sc_time_2019 in chunk above for chloropleth
sc_time_2019_selective <- sc_time_2019 %>% dplyr::rename(lat = LATITUDE) %>% dplyr::rename(long = LONGITUDE) %>%
dplyr::rename(state = STABBR) %>% filter(ADM_RATE < 0.3) %>%
dplyr::mutate(uni_rank = case_when(
ADM_RATE < 0.05 ~ 'elite',
ADM_RATE < 0.2 ~ 'highly selective',
TRUE ~ 'selective'))
sc_time_2019_selective <- sc_time_2019_selective %>% subset(DEBT_MDN !='PrivacySuppressed') %>%
transform(DEBT_MDN = as.numeric(DEBT_MDN)) %>%
dplyr::mutate(DEBT_MDN = ifelse(is.na(DEBT_MDN), 0, DEBT_MDN))
pal1 = colorFactor(ShortPuBuGn, domain = sc_time_2019_selective$`uni_rank`,reverse=TRUE)
#set popups
content <- paste("School",sc_time_2019_selective$INSTNM,"<br/>",
"Number of Undergrads:",sc_time_2019_selective$UGDS,"<br/>",
"Selectivity:", sc_time_2019_selective$uni_rank,"<br/>",
"Median Debt:",paste('$',round(sc_time_2019_selective$DEBT_MDN,2)),"<br/>")
sc_time_2019_selective
leaflet(sc_time_2019_selective) %>% addTiles('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png') %>%
addCircles(col = ~pal1(sc_time_2019_selective$uni_rank),
radius = ~DEBT_MDN,
popup = content,
fillOpacity = 0.7) %>%
leaflet::addLegend(position = "bottomleft",pal = pal1, values = sc_time_2019_selective$uni_rank,
title = "Average Student Loans (Per Student)")
?addLegend
setwd('~/Dropbox (Business)/Spring 2021/QMSS 5063 - Data Visualization /Group_G_HigherEd/')
sc_time <- read_csv('src/2010_2019_student_debt.csv')
sc_time
setwd("~/Dropbox (Business)/Spring 2021/QMSS 5063 - Data Visualization /Group_G_HigherEd")
sc_time <- read_csv('src/2010_2019_student_debt.csv')
sc_time<- sc_time %>% subset(DEBT_MDN !='PrivacySuppressed') %>%
transform(DEBT_MDN = as.numeric(DEBT_MDN)) %>%
dplyr::mutate(DEBT_MDN = ifelse(is.na(DEBT_MDN), 0, DEBT_MDN)) %>%
mutate(DEBT_MDN_STUDENT = DEBT_MDN*UGDS)
sc_time
library(reshape2)
library(shiny)
ui <- fluidPage(
titlePanel("I love Graphs about Student Debt"),
# selectInput('year',
# 'Year',
# choices=c(2010,2011,2012,2013,2014,2015,2016,2017,2018,2019)),
sliderInput(inputId = "year",
label = "Year",
value = c(2010,2011,2012,2013,2014,2015,2016,2017,2018,2019)),
leafletOutput("studentdebtmap")
)
server <- function(input, output, session){
# Render plot of top 10 most popular names
sc_time_selective <- reactive({sc_time %>% subset(Year_Ending == input$year) %>%
group_by(STABBR) %>% mutate(`Average Student Loans`=sum(DEBT_MDN_STUDENT,na.rm=TRUE)/sum(UGDS,na.rm=TRUE)) %>%
group_by(STABBR,`Average Student Loans`) %>% summarize()})
library(tigris)
states <- states(cb = TRUE)
states_year <- reactive({states %>% inner_join(sc_time_selective(), by=c(STUSPS='STABBR'))})
output$studentdebtmap <- renderLeaflet({
pal = colorFactor('Greens', domain = states_year()$`Average Student Loans`)
pop_pop <- paste("State:",states_year()$NAME,"<br/>",
"Average Student Loans","<br/>", "of Schools Located in State:",
paste('$',round(states_year()$`Average Student Loans`)))
sc_time_selective_title <- tags$p(tags$style('p{color:gray; font-size: 14px; family: serif}'),
tags$b('Average Debt By State (2019)'))
leaflet(states_year()) %>% addProviderTiles("CartoDB.Positron") %>%
addPolygons(fillColor = ~pal(states_year()$`Average Student Loans`),
color = "white",
weight = 0.5,
fillOpacity = 0.7,
highlight = highlightOptions(
weight = 5,
color = "#666",
fillOpacity = 0.7,
bringToFront = TRUE,
),popup=pop_pop) %>% addLegend(position = "bottomleft", colors =c("#EDF8E9","#BAE4B3","#74C476","#31A354","#006D2C"),
labels = c(paste('$',round(min(states_year()$`Average Student Loans`)))," "," "," ",
paste('$',round(max(states_year()$`Average Student Loans`)))),
title = "Average Student Loans (Per Student)") %>%
leaflet::setView(-98.5795, 39.8282, zoom=3) %>% addControl(sc_time_selective_title, position='topright')
})
observe({
leafletProxy("studentdebtmap", data = states_year())
})
}
shinyApp(ui = ui, server = server)
Not all schools have similar amounts of median student debt burden (i.e., upon the beginning of the repayment period). This map summarizes the median debt burden by the state that the school is located in. As shown in this plot, some states (including schools in Pennsylvania, Minnesota, Illinois, etc.) tend to have the highest average median debt burden between the schools within. These states do not necessarily house the most prestigious schools. One of the things we can see when disaggregating this way is that locationally there is a lot of diversity of the student loan burden (on average) given to students by schools when disaggregated at the state level (ranging from 4K to 18K USD in 2019) Note that we have also included the shiny interactivity component in which one can select the year on the slider to see the state-level debt median disaggregation across the years; this is not the primary function but instead is a functionality we added to allow individuals to ‘explore the data’ a bit.
ui <- fluidPage(
titlePanel('The Cost of Higher Education: An Exploration of Student Debt in American Universities')
)
<<<<<<< Updated upstream
LS0tCnRpdGxlOiAiVmlzdWFsc19EcmFmdF8wNF8xNCIKYXV0aG9yOiAiQ29ubmllIFh1IgpkYXRlOiAiNC8xNC8yMDIxIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Kc2V0d2QoIn4vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZC9zcmMvdmlzdWFscy8iKQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCnNvdXJjZSgib3VydGhlbWUuUiIpCmBgYAoKYGBge3IgcGFja2FnZXMsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KciA9IGdldE9wdGlvbigicmVwb3MiKQpyWyJDUkFOIl0gPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIKb3B0aW9ucyhyZXBvcyA9IHIpCiMgaW5zdGFsbC5wYWNrYWdlcyAoYmFzaWMpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShkcGx5cikpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQoKIyBpbnN0YWxsLnBhY2thZ2VzIChyZWFkaW5nKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoWE1MKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KFJDdXJsKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHJlYWRyKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KCJyZWFkeGwiKSkKCiMgaW5zdGFsbC5wYWNrYWdlcyAodGhlbWVzKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2d0aGVtZXMpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2dyZXBlbCkpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShSQ29sb3JCcmV3ZXIpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkodmlyaWRpcykpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShocmJydGhlbWVzKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHBsb3RseSkpCgoKIyBpbnN0YWxsLnBhY2thZ2VzIChtYXBzKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoUmdvb2dsZU1hcHMpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2dtYXApKQpzdXBwcmVzc01lc3NhZ2VzKGluc3RhbGwucGFja2FnZXMoIm1hcHMiKSkKc3VwcHJlc3NNZXNzYWdlcyhpbnN0YWxsLnBhY2thZ2VzKCJ0bWFwIikpICMgaW5zdGFsbCB0aGUgQ1JBTiB2ZXJzaW9uCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeSh0bWFwKSkKc3VwcHJlc3NNZXNzYWdlcyhpbnN0YWxsLnBhY2thZ2VzKCdyZ2VvcycpKQoKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGRldnRvb2xzKSkKIyBMZXQncyBpbnN0YWxsIHRoZSBkZXZlbG9wbWVudCB2ZXJzaW9uIGZyb20gR2l0aHViLiBSdW4KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJyc3R1ZGlvL2xlYWZsZXQiKQpgYGAKCmBgYHtyIGltcG9ydCBnZW5lcmFsIGRhdGEsIGVjaG89VFJVRSwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFNldCB0aGUgV0QgYXMgR3JvdXBfR19IaWdoZXJFZCAKc2V0d2QoIn4vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZCIpCgojIFdoaWxlIG91ciBpbml0aWFsIENvbGxlZ2UgU2NvcmVjYXJkIG9ubHkgaW5jbHVkZWQgMjAxOSBpbml0aWFsbHksIEkgd2FzIGFibGUgdG8gcnVuIGEgc2ltcGxlIHB5dGhvbiBzY3JpcHQgdG8gY29uY2F0ZW5hdGUgYW5kIHNlbGVjdCBhIHNtYWxsIG51bWJlciBvZiByZWxldmFudCBjb2x1bW5zIGZvciBvdXIgdmlzdWFsaXphdGlvbiBhbmQgYW5hbHlzaXMuIFRodXMsIGFzIG91ciBmaXJzdCB2aXN1YWxpemF0aW9ucyBvbmx5IHVuY2x1ZGUgMjAxOSwgdGhlIGNvZGUgYmVsb3cgaXMgZm9yIHJlLWZpbHRlcmluZyB0aGUgY29uY2F0ZW5hdGVkIDIwMTAtMjAxOSBkYXRhIGJhY2sgaW50byBzaW1wbHkgMjAxOS4gCgpzY190aW1lIDwtIHJlYWQuY3N2KCcvc3JjLzIwMTBfMjAxOV9zdHVkZW50X2RlYnQuY3N2JykgCnNjIDwtIHNjX3RpbWUgJT4lIGZpbHRlcihZZWFyX0VuZGluZyA9PSAyMDE5KQpzY190aW1lCmxpYnJhcnkoZWR1Y2F0aW9uZGF0YSkKIyBUZXN0IFJ1biB3aXRoIHVzaW5nIGdldF9lZHVjYXRpb25fZGF0YSAKIyBkYXRhIDwtIGdldF9lZHVjYXRpb25fZGF0YShsZXZlbCA9ICJjb2xsZWdlLXVuaXZlcnNpdHkiLAojICAgICBzb3VyY2UgPSAiaXBlZHMiLAojICAgICB0b3BpYyA9ICJkaXJlY3RvcnkiLAojICAgICBmaWx0ZXJzID0gbGlzdCh5ZWFyID0gMjAxOSkpCiMgZGF0YQojIFNjb3JlY2FyZCBkYXRhIC0gMjAxOSAKCiMjIGNoYW5nZSBwcm9qZWN0aW9uIG9mIHNjIGRhdGEKc2MgPC0gc2MgJT4lCiAgZHBseXI6Om11dGF0ZSh1bmlfcmFuayA9IGNhc2Vfd2hlbigKICAgIEFETV9SQVRFIDwgMC4yIH4gJ2hpZ2hseSBzZWxlY3RpdmUvZWxpdGUnLAogICAgQURNX1JBVEUgPCAwLjMgfiAnbW9yZSBzZWxlY3RpdmUnLAogICAgQURNX1JBVEUgPCAwLjUgfiAnc2VsZWN0aXZlJywKICAgIEFETV9SQVRFIDwgMC43IH4gJ2xlc3Mgc2VsZWN0aXZlJywKICAgIFRSVUUgfiAnbm90IHNlbGVjdGl2ZScpKSAlPiUgbXV0YXRlKHVuaV9yYW5rID0gZmFjdG9yKHVuaV9yYW5rLCBsZXZlbHM9Yygnbm90IHNlbGVjdGl2ZScsICdsZXNzIHNlbGVjdGl2ZScsICdzZWxlY3RpdmUnLCAnbW9yZSBzZWxlY3RpdmUnLCAnaGlnaGx5IHNlbGVjdGl2ZS9lbGl0ZScpKSkKYGBgCgojIyBTaW1wbGUgU2NhdHRlcmdyYW0gCgpGaXJzdCB3ZSBhcmUgZ29pbmcgdG8gdHJ5IHRvIHByZXNlbnQgdGhpcyBwYXR0ZXJuIGZvciBkaWZmZXJlbnQgdGllcnMgb2YgdW5pdmVyc2l0aWVzIChhZG1pc3Npb24gcmF0ZSBhcyB3ZWxsIGFzIGRlYnQpCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KIyBSZW1vdmUgUHJpdmFjeVN1cHByZXNzZWQgUmVjb3JkcyBhbmQgdHJhbnNmb3JtIERlYnQgTWVkaWFuIGludG8gYSBudW1lcmljIHZhbHVlIC0gd2UgY2FuIGFsc28gZG8gdGhpcyBvbiB0aGUgbWFpbiBzYyBkZgpzYyRERUJUX01ETltpcy5uYShzYyRERUJUX01ETildIDwtIDA7CgpicmV3ZXIucGFsKG49MTAsIlB1QnVHbiIpClNob3J0UHVCdUduIDwtIGMoIiNEMEQxRTYiLCIjQTZCRERCIiwiIzY3QTlDRiIsIiMzNjkwQzAiLCIjMDI4MThBIikKCm0gPC0gc2MgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogICAgICAgICAgICAgIGdncGxvdCguLCBhZXMoeD1BRE1fUkFURSwgeT1ERUJUX01ETixjb2xvcj11bmlfcmFuaykpICsKICBnZW9tX3BvaW50KHBjaD0yMSkgKwogIGdlb21fc21vb3RoKGNvbG9yPSduYXZ5Jywgc2UgPSBGQUxTRSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9U2hvcnRQdUJ1R24pKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5iYWNrZ3JvdW5kPSBlbGVtZW50X3JlY3QoZmlsbD0id2hpdGUiKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPWMoMCwxMDAwMCwyMDAwMCwzMDAwMCksIGxhYmVscz1jKCcwJywnMTAnLCcyMCcsJzMwJykpICsKICBsYWJzKHg9J0FkbWlzc2lvbnMgUmF0ZScsIHk9J01lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTdHVkZW50IERlYnQgYW5kIEFkbWlzc2lvbnMgUmF0ZScsCiAgICAgICBjb2xvcj0nU2VsZWN0aXZpdHknKQptCmBgYAogIAogIFRoaXMgcGxvdCBzZXRzIG91dCB0byBzaG93IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtZWRpYW4gbG9hbiBhbW91bnQgaW4gMjAxOSBhbmQgdGhlIGFkbWlzc2lvbnMgcmF0ZS4gVGhlIHRyZW5kIHNob3duIGhlcmUgaXMgdGhhdCBhcyB0aGUgYWRtaXNzaW9ucyByYXRlIGdvZXMgdXAgKGkuZS4sIGFzIHNjaG9vbHMgYmVjb21lIGxlc3Mgc2VsZWN0aXZlKSwgc28gZG9lcyBtZWRpYW4gbG9hbiBhbW91bnQgKGF0IGxlYXN0IHVudGlsIHdlIGdvIGZyb20gbGVzcyBzZWxlY3RpdmUgdG8gbm90IHNlbGVjdGl2ZSkuIEJhc2VkIG9uIHRoZSBzY2F0dGVycGxvdCwgaXQgY2FuIGFsc28gYmUgc2VlbiB0aGF0IHRoZSB2YXJpYW5jZSBnb2VzIHVwIGluIHRlcm1zIG9mIG1lZGlhbiBzdHVkZW50IGxvYW4gYW1vdW50IChhbHRob3VnaCBpdCBjYW4gYWxzbyBiZSBzZWVuIHRoYXQgdGhpcyBpcyBwYXJ0aWFsbHkgZHVlIHRvIHRoZSBtdWNoIGxhcmdlciBudW1iZXIgb2Ygc2Nob29scyBpbiB0aGUgbGVzcyBzZWxlY3RpdmUgYnVja2V0cykuICAKICBUaGlzIGlzIHNvbWV3aGF0IGludGVyZXN0aW5nIGJlY2F1c2UgbW9yZSBleGNsdXNpdmUvc2VsZWN0aXZlIHNjaG9vbHMgYXJlIG9uIGF2ZXJhZ2Ugdmlld2VkIGFzIG1vcmUgJ2NvbXBldGl0aXZlJyBhbmQgJ3ByZXN0aWdpb3VzJyAoZS5nLiwgSGFydmFyZCwgU3RhbmZvcmQsIGV0Yy4pOyBhIGdyZWF0IGRlYWwgb2YgZXhpc3RlbnQgbGl0ZXJhdHVyZSBoYXMgbm90ZWQgdGhhdCBzdWNoICdwcmVzdGlnaW91cycgc2Nob29scyBvZnRlbiBlbmQgdXAgYWRtaXR0aW5nIG1vcmUgcGVvcGxlIGZyb20gZWNvbm9taWNhbGx5IHByaXZpbGVnZWQgYmFja2dyb3VuZHMgKG91dHNpZGUgb2YgdGhvc2UgYWRtaXR0ZWQgc3BlY2lmaWNhbGx5IGZvciBkaXZlcnNpdHkpLCBhcyAnbWVyaXQtYmFzZWQnIGFkbWlzc2lvbnMgb2Z0ZW4gY29ycmVsYXRlIHdpdGggYWNjZXNzIHRvIGVjb25vbWljIGFuZCBmaW5hbmNpYWwgcmVzb3VyY2VzLCB3aGljaCBhbGxvdyBmb3IgYWNjZXNzIHRvIHJlc291cmNlcyBoZWxwZnVsIGZvciBjb21wZXRlbmNlIHNpZ25hbGxpbmcsIHN1Y2ggYXMgc3RhbmRhcmRpemVkIHRlc3QgcHJlcCBjb3Vyc2VzLCBzcG9ydHMgYW5kIGFjdGl2aXRpZXMsIGV0YzsgZnVydGhlcm1vcmUsIHN1Y2ggc2Nob29scyBpbmNsdWRlIG1vcmUgZmluYW5jaWFsIHJlc291cmNlcyAoYXMgbW9yZSBwcmVzdGlnaW91cyBzY2hvb2xzIHByb2R1Y2UgYWxtYSBtYXRlcnMgd2l0aCBoaWdoZXIgc29jaW9lY29ub21pYyBvdXRjb21lcykgYW5kIHRodXMgcG90ZW50aWFsbHkgY2FuIGhlbHAgbW9yZSB3aXRoIGZpbmFuY2lhbCBhaWQgYW5kIHNjaG9sYXJzaGlwcy4gCiAgClRoaXMgaXMgYSBkYXRhIHRhYmxlIHNob3dpbmcgdGhlIGJyZWFrZG93biBvZiB0aGUgdW5pdmVyc2l0eSByYW5rcyAoYXMgSSBjaG9zZSB0byByYW5rIHRoZW0pLiBJIHdpbGwgbm90ZSB0aGF0IGZyb20gdGhlIGR0IGFsb25lIHd3ZSBhcmUgc2VlaW5nIGEgZG93bndhcmQgdHJlbmQgaW4gdGhlICdNZWRpYW4gU3R1ZGVudCBMb2FucycgY29sdW1uLiAKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQojIENyZWF0ZSBEYXRhIFRhYmxlIChTdW1tYXJpemVkKSBmb3IgCmxpYnJhcnkoJ3NjYWxlcycpCgpzY19kdCA8LSBzYyAlPiUgc3Vic2V0KERFQlRfTUROICE9J1ByaXZhY3lTdXBwcmVzc2VkJykgJT4lIHRyYW5zZm9ybShERUJUX01ETiA9IGFzLm51bWVyaWMoREVCVF9NRE4pKSAlPiUgZ3JvdXBfYnkodW5pX3JhbmspICU+JSBtdXRhdGUoYE51bWJlciBvZiBVbml2ZXJzaXRpZXNgID0gbigpKSAlPiUgdW5ncm91cCgpICU+JSBtdXRhdGUoREVCVF9NRE5fU1RVREVOVFMgPSBERUJUX01ETipVR0RTKSAlPiUgZ3JvdXBfYnkodW5pX3JhbmspICU+JSBtdXRhdGUoYE1lZGlhbiBTdHVkZW50IExvYW5zYCA9IHBhc3RlKCckJyxyb3VuZChzdW0oREVCVF9NRE5fU1RVREVOVFMsIG5hLnJtPVRSVUUpL3N1bShVR0RTLCBuYS5ybT1UUlVFKSwyKSkpICU+JSAKICBtdXRhdGUoYE1pbiBBY2NlcHRhbmNlIFJhdGVgID0gcGVyY2VudChtaW4oQURNX1JBVEUpKSkgJT4lIG11dGF0ZShgTWF4IEFjY2VwdGFuY2UgUmF0ZWAgPSBwZXJjZW50KG1heChBRE1fUkFURSkpKSAlPiUgdW5ncm91cCgpICU+JSAKICBncm91cF9ieSh1bmlfcmFuayxgTWVkaWFuIFN0dWRlbnQgTG9hbnNgLGBOdW1iZXIgb2YgVW5pdmVyc2l0aWVzYCxgTWluIEFjY2VwdGFuY2UgUmF0ZWAsYE1heCBBY2NlcHRhbmNlIFJhdGVgKSAlPiUgCiAgc3VtbWFyaXplKCkgJT4lIGRwbHlyOjpyZW5hbWUoYFVuaXZlcnNpdHkgU2VsZWN0aXZpdHlgID0gdW5pX3JhbmspCgppbnN0YWxsLnBhY2thZ2VzKCdEVCcpCmxpYnJhcnkoRFQpCnRhYmxlIDwtIGRhdGF0YWJsZShzY19kdCxzdHlsZSA9ICJkZWZhdWx0IixmaWx0ZXIgPSAndG9wJywgIGNhcHRpb24gPSAnVW5pdmVyc2l0aWVzIGFuZCBTZWxlY3Rpdml0eScpCnRhYmxlCgpgYGAKVGhpcyBkYXRhIHRhYmxlIHN1bW1hcml6ZXMgaG93IHdlIGNhdGVnb3JpemVkIG91ciB2YXJpYWJsZSBmb3IgdW5pdmVyc2l0eSBzZWxlY3Rpdml0eSBncm91cGluZyAoZnJvbSB0aGUgQ29sbGVnZSBTY29yZWNhcmQgZmlsZSkuIEl0IGRlc2NyaWJlcyB0aGUgbWVkaWFuIHN0dWRlbnQgbG9hbnMgYW5kIHRoZSBudW1iZXIgb2YgdW5pdmVyc2l0aWVzIGluIGVhY2ggY2F0ZWdvcnkgYXMgb2YgMjAxOSwgYXMgd2VsbCBhcyB0aGUgTWluaW11bSBBY2NlcHRhbmNlIFJhdGUsIGFuZCB0aGUgTWF4aW11bSBBY2NlcHRhbmNlIFJhdGUgdGhyZXNob2xkcy4gCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygndHJlZW1hcCcpCmluc3RhbGwucGFja2FnZXMoJ2hpZ2hjaGFydGVyJykKbGlicmFyeShoaWdoY2hhcnRlcikKbGlicmFyeSh0cmVlbWFwKQoKc2NfZHQgJT4lIGRwbHlyOjptdXRhdGUoRGVzY3JpcHRpb249cGFzdGUoYFVuaXZlcnNpdHkgU2VsZWN0aXZpdHlgLCAnXG4nLGBOdW1iZXIgb2YgVW5pdmVyc2l0aWVzYCwnVW5pdmVyc2l0aWVzJyksIHNlcCA9IlxuIikgJT4lCiAgdHJlZW1hcChpbmRleD0iRGVzY3JpcHRpb24iLAogICAgICAgICAgdlNpemU9Ik51bWJlciBvZiBVbml2ZXJzaXRpZXMiLAogICAgICAgIHR5cGU9ImluZGV4IiwKICAgICAgICBmb250c2l6ZS5sYWJlbHM9YygxMiwgOCksIAogICAgICAgIHBhbGV0dGUgPSAgdmlyaWRpcyg1KSwKICAgICAgICBib3JkZXIuY29sPSJ3aGl0ZSIsCiAgICAgICAgdGl0bGUgPSAnVW5pdmVyc2l0aWVzIGFuZCBTZWxlY3Rpdml0eScpCmBgYAoKICBUaGUgdHJlZW1hcCBhYm92ZSB2aXN1YWxpemVzIGFuZCBzdW1tYXJpemVzIHRoZSBzZWxlY3Rpdml0eSBncm91cGluZyBsYWJlbCBhbmQgdW5pdmVyc2l0eSBjb3VudHMgd2l0aGluIGVhY2ggb2YgdGhlIGNhdGVnb3JpY2FsIHNlbGVjdGl2aXR5IGdyb3VwaW5ncy4gQXMgc2hvd24gYWJvdmUsIHRoZSB2YXN0IG1ham9yaXR5IG9mIHNjaG9vbHMgaW4gb3VyIGRhdGFzZXQgd2VyZSAnbm90IHNlbGVjdGl2ZScgb3IgJ2xlc3Mgc2VsZWN0aXZlJzsgaG93ZXZlciwgbWFueSBvZiBvdXIgYW5hbHlzZXMgZm9jdXMgb24gdGhlIHNtYWxsZXIgY2F0ZWdvcmllcyAocGFydGljdWxhcmx5IHNlbGVjdGl2ZSB0byBoaWdobHkgc2VsZWN0aXZlL2VsaXRlKSwgYmVjYXVzZSB0aGVzZSBjYXRlZ29yaWVzIGhhdmUgbW9yZSB3aXRoaW4tZ3JvdXAgaG9tb2dlbmVpdHkgYW5kIGZ1cnRoZXJtb3JlIGFyZSBtb3JlIGludGVyZXN0aW5nIHRvIG91ciBmb2NhbCBxdWVzdGlvbnMuIAoKIyMgU2NhdHRlcmdyYW0gYXMgVmlvbGluIFBsb3QKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQptIDwtIHNjICU+JSBzdWJzZXQoREVCVF9NRE4gIT0nUHJpdmFjeVN1cHByZXNzZWQnKSAlPiUgdHJhbnNmb3JtKERFQlRfTUROID0gYXMubnVtZXJpYyhERUJUX01ETikpICU+JSAKICBnZ3Bsb3QoLiwgYWVzKHg9dW5pX3JhbmssIHk9REVCVF9NRE4pKSArCiAgZ2VvbV92aW9saW4oYWVzKGZpbGw9dW5pX3JhbmssY29sb3I9dW5pX3JhbmspKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4yKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9U2hvcnRQdUJ1R24pICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1TaG9ydFB1QnVHbikgKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5iYWNrZ3JvdW5kPSBlbGVtZW50X3JlY3QoZmlsbD0id2hpdGUiKSkrCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9YygwLDEwMDAwLDIwMDAwLDMwMDAwKSwgbGFiZWxzPWMoJzAnLCcxMCcsJzIwJywnMzAnKSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoJ25vdFxuc2VsZWN0aXZlXG4oPjcwJSknLCdsZXNzXG5zZWxlY3RpdmVcbig1MCUtNzAlKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0aXZlXG4oMzAlLTUwJSknLCdtb3JlXG5zZWxlY3RpdmVcbigyMCUtMzAlKScsJ2hpZ2hseVxuc2VsZWN0aXZlXG4oNSUtMjAlKScsJ2VsaXRlXG4oPDUlKScpKSArCgogIGxhYnMoeD0nU2VsZWN0aXZpdHlcbihhZG1pc3Npb24gcmF0ZSB0aHJlc2hvbGRzKScsIHk9J01lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTZWxlY3RpdmUgU2Nob29scyBhbmQgU3R1ZGVudCBEZWJ0JywKICAgICAgIGNvbG9yPScnLGZpbGw9JycpCm0KYGBgClNob3dpbmcgdGhlIHByZXZpb3VzIHNjYXR0ZXJncmFtIHNwZWNpZmljYWxseSBhcyB2aW9saW4gcGxvdHMKCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KaXBlZHMxNSA8LSBnZXRfZWR1Y2F0aW9uX2RhdGEobGV2ZWwgPSAiY29sbGVnZS11bml2ZXJzaXR5IiwKICAgIHNvdXJjZSA9ICJpcGVkcyIsCiAgICB0b3BpYyA9ICJncmFkLXJhdGVzLXBlbGwiLAogICAgZmlsdGVycyA9IGxpc3QoeWVhciA9IDIwMTUpKQppcGVkczE1CmBgYAoKCiMjIFN0dWRlbnQgRGVidCBvdmVyIFRpbWUKCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNQcm9jZXNzIHRoZSBkYXRhIApzY190aW1lIDwtIHJlYWRfY3N2KCcyMDEwXzIwMTlfc3R1ZGVudF9kZWJ0LmNzdicpIAoKc2NfdGltZTwtIHNjX3RpbWUgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSAKICB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoREVCVF9NRE4gPSBpZmVsc2UoaXMubmEoREVCVF9NRE4pLCAwLCBERUJUX01ETikpCgpgYGAKCgpgYGB7ciwgZWNobz1UUlVFLCBldmFsPVRSVUV9CiNQcm9jZXNzIHRoZSBkYXRhIApzZXR3ZCgifi9Ecm9wYm94IChCdXNpbmVzcykvU3ByaW5nIDIwMjEvUU1TUyA1MDYzIC0gRGF0YSBWaXN1YWxpemF0aW9uIC9Hcm91cF9HX0hpZ2hlckVkIikKc2NfdGltZSA8LSByZWFkX2Nzdignc3JjLzIwMTBfMjAxOV9zdHVkZW50X2RlYnQuY3N2JykgCnNjX3RpbWU8LSBzY190aW1lICU+JSBzdWJzZXQoREVCVF9NRE4gIT0nUHJpdmFjeVN1cHByZXNzZWQnKSAlPiUgCiAgdHJhbnNmb3JtKERFQlRfTUROID0gYXMubnVtZXJpYyhERUJUX01ETikpICU+JSAKICBkcGx5cjo6bXV0YXRlKERFQlRfTUROID0gaWZlbHNlKGlzLm5hKERFQlRfTUROKSwgMCwgREVCVF9NRE4pKSAlPiUgCiAgbXV0YXRlKERFQlRfTUROX1NUVURFTlQgPSBERUJUX01ETipVR0RTKQpzY190aW1lCgpzdW0oc2NfdGltZSRVR0RTLG5hLnJtPVRSVUUpCmBgYAoKQmVsb3cgaXMgYW4gaW50ZXJhY3RpdmUgbGluZSBncmFwaCAoMjAxMC0yMDE5KSB3aGljaCBkZXRhaWxzIHRoZSB0cmVuZHMgaW4gc3R1ZGVudCBkZWJ0IG92ZXIgdGhlIHllYXJzLiAKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQojIENQSSBJbmZsYXRpb24gUmF0ZXMgLSBHb3QgQXZlcmFnZSBZZWFybHkgSW5mbGF0aW9uIFJhdGUgZm9yIFNjYWxpbmcgZm9yIFN0dWRlbnQgRGVidCAKaW5zdGFsbC5wYWNrYWdlcygncXVhbnRtb2QnKQpsaWJyYXJ5KHF1YW50bW9kKQpnZXRTeW1ib2xzKCJDUElBVUNTTCIsIHNyYz0nRlJFRCcpCmF2Zy5jcGkgPC0gYXBwbHkueWVhcmx5KENQSUFVQ1NMLCBtZWFuKQpjZiA8LSBhcy5kYXRhLmZyYW1lKGF2Zy5jcGkvYXMubnVtZXJpYyhhdmcuY3BpWycyMDA5J10pKSAKY2YkWWVhcl9FbmRpbmcgPC0gZm9ybWF0KGFzLkRhdGUocm93Lm5hbWVzKGNmKSwgZm9ybWF0PSIlWS0lbS0lZCIpLCIlWSIpCgojIE1lcmdlZCBmb3IgSW5mbGF0aW9uIApzY190aW1lX2RmIDwtIHNjX3RpbWUgJT4lIGdyb3VwX2J5KGBZZWFyX0VuZGluZ2ApICU+JSBtdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCA9IHN1bShERUJUX01ETl9TVFVERU5ULG5hLnJtPVRSVUUpL3N1bShVR0RTLG5hLnJtPVRSVUUpKSAlPiUgdW5ncm91cCgpICU+JSAKICBkcGx5cjo6bXV0YXRlKHVuaV9yYW5rID0gY2FzZV93aGVuKAogICAgQURNX1JBVEUgPCAwLjIgfiAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScsCiAgICBBRE1fUkFURSA8IDAuMyB+ICdtb3JlIHNlbGVjdGl2ZScsCiAgICBBRE1fUkFURSA8IDAuNSB+ICdzZWxlY3RpdmUnLAogICAgQURNX1JBVEUgPCAwLjcgfiAnbGVzcyBzZWxlY3RpdmUnLAogICAgVFJVRSB+ICdub3Qgc2VsZWN0aXZlJykpICU+JQogIG11dGF0ZSh1bmlfcmFuayA9IGZhY3Rvcih1bmlfcmFuaywgbGV2ZWxzPWMoJ25vdCBzZWxlY3RpdmUnLCAnbGVzcyBzZWxlY3RpdmUnLCAnc2VsZWN0aXZlJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9yZSBzZWxlY3RpdmUnLCAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScpKSkgJT4lCiAgZ3JvdXBfYnkodW5pX3JhbmssWWVhcl9FbmRpbmcpICU+JSAKICBtdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAoYnkgU2VsZWN0aXZpdHkpYCA9IHN1bShERUJUX01ETl9TVFVERU5ULG5hLnJtPVRSVUUpL3N1bShVR0RTLG5hLnJtPVRSVUUpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShgWWVhcl9FbmRpbmdgLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAsCiAgICAgICAgICAgdW5pX3JhbmssYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCkgJT4lIHN1bW1hcml6ZSgpICU+JSAKICBtZXJnZShjZikgJT4lIAogIG11dGF0ZShgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCA9IGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAvCiAgICAgICAgICAgQ1BJQVVDU0wpICU+JSAKICBtdXRhdGUoYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWAgPSBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgLwogICAgICAgICAgIENQSUFVQ1NMKQoKc2NfZGYgPC0gc2NfdGltZV9kZiAlPiUgZ3JvdXBfYnkoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCxgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gQ29tcG9zaXRlYCxZZWFyX0VuZGluZykgJT4lIHN1bW1hcml6ZSgpICU+JSBtdXRhdGUodW5pX3Jhbms9J25hdGlvbmFsIGF2ZXJhZ2UnKSAlPiUgbXV0YXRlKGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnRgPWBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgKSAlPiUgZHBseXI6Om11dGF0ZShgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgID0gYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCkgJT4lIG1lcmdlKGNmKSAlPiUgc2VsZWN0KFllYXJfRW5kaW5nLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAsIHVuaV9yYW5rLCBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgLCBDUElBVUNTTCwgYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidGAsYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWApCnNjX3RpbWVfZGYgPC0gc2NfdGltZV9kZiAlPiUgcmJpbmQoc2NfZGYpICU+JSBtdXRhdGUodW5pX3JhbmsgPSBmYWN0b3IodW5pX3JhbmssIGxldmVscz1jKCduYXRpb25hbCBhdmVyYWdlJywnbm90IHNlbGVjdGl2ZScsICdsZXNzIHNlbGVjdGl2ZScsICdzZWxlY3RpdmUnLCAnbW9yZSBzZWxlY3RpdmUnLCAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScpKSkgJT4lIAogIG11dGF0ZShgR3JvdXAgTGV2ZWxgID0gaWZlbHNlKHVuaV9yYW5rID09ICduYXRpb25hbCBhdmVyYWdlJywgJ05hdGlvbmFsJywnU2VsZWN0aXZpdHknKSkKc2NfZGYKc2NfdGltZV9kZgoKCnAgPC0gc2NfdGltZV9kZiAlPiUgCiAgZ2dwbG90KC4sYWVzKHg9WWVhcl9FbmRpbmcseT1gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCwgY29sb3I9dW5pX3JhbmspKSArIAogIGdlb21fbGluZShhZXMobGluZXR5cGU9YEdyb3VwIExldmVsYCkpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdncmV5JywiI0QwRDFFNiIsIiNBNkJEREIiLCIjNjdBOUNGIiwiIzM2OTBDMCIsIiMwMjgxOEEiKSkrCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiKSkrCiAgdGhlbWUoCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmJhY2tncm91bmQ9IGVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHJvdW5kKHNlcShtaW4oc2NfdGltZSRZZWFyX0VuZGluZyksIG1heChzY190aW1lJFllYXJfRW5kaW5nKSwgYnkgPSAyKSwxKSkgKwogIGxhYnMoeD0nJywgeT0nSW5mbGF0aW9uLUFkanVzdGVkIE1lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTdHVkZW50IERlYnQgSGFzIEJlZW4gUmlzaW5nIE92ZXIgVGhlIFllYXJzJywKICAgICAgIGNvbG9yPScnLGZpbGw9JycsZ3JvdXA9JycsbGluZXR5cGU9JycpCmdncGxvdGx5KHApCgoKYGBgCgogIEJldHdlZW4gMjAxMCBhbmQgMjAxOCwgdGhlIG1lZGlhbiBsb2FuIGFtb3VudCBwZXIgc3R1ZGVudCBpbmNyZWFzZWQgYnkgMjAwMC00MDAwKyBVU0QgKGluZmxhdGlvbi1hZGp1c3RlZCkgLSBuYXRpb25hbGx5LCB0aGUgbWVkaWFuIHN0dWRlbnQgbG9hbiBhbW91bnQgaW5jcmVhc2VkIGJ5IDE5JS4gV2hlbiBvbmUgZGlzYWdncmVnYXRlcyB1bml2ZXJzaXRpZXMgYnkgc2VsZWN0aXZpdHksIHdlIHNlZSB0aGUgc2FtZSAqb3ZlcmFsbCogdHJlbmQgb3ZlciB0aW1lIChpLmUuLCB0aGVyZSBpcyBhIGZhaXIgYW1vdW50IG9mIGluY3JlYXNlIGR1cmluZyB0aGUgcGVyaW9kIGluIHRlcm1zIG9mIGF2ZXJhZ2Ugc3R1ZGVudCBsb2FucyB0aGF0IHN0dWRlbnRzIGxlYXZlIHdpdGggdXBvbiBlbnRlcmluZyByZXBheW1lbnQpOyBob3dldmVyLCBzb21lIHNlbGVjdGl2aXR5IGdyb3VwcyBpbmNyZWFzZWQgbW9yZSBkcmFtYXRpY2FsbHkgdGhhbiBvdGhlcnMgKGUuZy4sICdNb3JlIFNlbGVjdGl2ZScgb3Igc2Nob29scyB3aXRoIDIwLTMwJSBhY2NlcHRhbmNlIHJhdGVzIGFwcGVhcmVkIHRvIGluY3JlYXNlIGdyZWF0bHkgaW4gdGVybXMgb2Ygc3R1ZGVudCBkZWJ0IHByaW5jaXBhbCBiZXR3ZWVuIDIwMTUgYW5kIDIwMTcsIGJ1dCB0aGlzIGFtb3VudCBkZWNsaW5lZCBhIGJpdCBhZ2FpbiBpbiAyMDE4KSBhbmQgZGlmZmVyZW50IHNlbGVjdGl2aXR5IGdyb3VwcyBkZWNyZWFzZWQgaW4gbWVkaWFuIHN0dWRlbnQgZGVidCBvdmVyIHRpbWUgKGxlc3Mgc2VsZWN0aXZlOyBzZWxlY3RpdmUgc2Nob29scyBzZWVtZWQgdG8gZGVjcmVhc2UgaW4gbWVkaWFuIGRlYnQgZm9sbG93aW5nIDIwMTQpLiAgCiAgVG8gbG9vayBhdCBob3cgbWVkaWFuIHN0dWRlbnQgZGVidCBoYXMgY2hhbmdlZCBlaXRoZXIgYnkgb25seSBuYXRpb25hbCBhdmVyYWdlIG9yIHRvIGxvb2sgYXQgc3BlY2lmaWMgJ3NlbGVjdGl2aXR5JyBidWNrZXRzLCBvbmUgY2FuIHNpbXBseSBjbGljayB0byByZW1vdmUgdGhlIHJlbWFpbmluZyBsaW5lcyBpbiB0aGUgcGxvdC4gCgpUaGUgZm9sbG93aW5nIGlzIChpbnN0ZWFkKSBhIGJhciBncmFwaCB3aXRoIGZld2VyICd1bml2ZXJzaXR5IHNlbGVjdGl2aXR5JyBidWNrZXRzLiAKYGBge3J9CnNjX3RpbWVfZGYgPC0gc2NfdGltZSAlPiUgZ3JvdXBfYnkoYFllYXJfRW5kaW5nYCkgJT4lIG11dGF0ZShgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgID0gc3VtKERFQlRfTUROX1NUVURFTlQsbmEucm09VFJVRSkvc3VtKFVHRFMsbmEucm09VFJVRSkpICU+JSB1bmdyb3VwKCkgJT4lIAogIGRwbHlyOjptdXRhdGUodW5pX3JhbmsgPSBjYXNlX3doZW4oCiAgICBBRE1fUkFURSA8IDAuMiB+ICdoaWdobHkgc2VsZWN0aXZlJywKICAgIEFETV9SQVRFIDwgMC41IH4gJ21vZGVyYXRlbHkgc2VsZWN0aXZlJywKICAgIFRSVUUgfiAnbGVzcy9ub3QgYXQgYWxsIHNlbGVjdGl2ZScpKSAlPiUKICBtdXRhdGUodW5pX3JhbmsgPSBmYWN0b3IodW5pX3JhbmssIGxldmVscz1jKCdsZXNzL25vdCBhdCBhbGwgc2VsZWN0aXZlJywgJ21vZGVyYXRlbHkgc2VsZWN0aXZlJywgJ2hpZ2hseSBzZWxlY3RpdmUnKSkpICU+JQogIGdyb3VwX2J5KHVuaV9yYW5rLFllYXJfRW5kaW5nKSAlPiUgCiAgbXV0YXRlKGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAgPSBzdW0oREVCVF9NRE5fU1RVREVOVCxuYS5ybT1UUlVFKS9zdW0oVUdEUyxuYS5ybT1UUlVFKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoYFllYXJfRW5kaW5nYCxgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLAogICAgICAgICAgIHVuaV9yYW5rLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGApICU+JSBzdW1tYXJpemUoKSAlPiUgCiAgbWVyZ2UoY2YpICU+JSAKICBtdXRhdGUoYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidGAgPSBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLwogICAgICAgICAgIENQSUFVQ1NMKSAlPiUgCiAgbXV0YXRlKGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgID0gYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYC8KICAgICAgICAgICBDUElBVUNTTCkKCnNjX2RmIDwtIHNjX3RpbWVfZGYgJT4lIGdyb3VwX2J5KGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGAsYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWAsWWVhcl9FbmRpbmcpICU+JSBzdW1tYXJpemUoKSAlPiUgbXV0YXRlKHVuaV9yYW5rPSduYXRpb25hbCBhdmVyYWdlJykgJT4lIG11dGF0ZShgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YD1gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gQ29tcG9zaXRlYCkgJT4lIGRwbHlyOjptdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAoYnkgU2VsZWN0aXZpdHkpYCA9IGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGApICU+JSBtZXJnZShjZikgJT4lIHNlbGVjdChZZWFyX0VuZGluZyxgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLCB1bmlfcmFuaywgYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCwgQ1BJQVVDU0wsIGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnRgLGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgKQpzY190aW1lX2RmIDwtIHNjX3RpbWVfZGYgJT4lIHJiaW5kKHNjX2RmKSAlPiUgbXV0YXRlKHVuaV9yYW5rID0gZmFjdG9yKHVuaV9yYW5rLCBsZXZlbHM9YygnbmF0aW9uYWwgYXZlcmFnZScsJ2xlc3Mvbm90IGF0IGFsbCBzZWxlY3RpdmUnLCAnbW9kZXJhdGVseSBzZWxlY3RpdmUnLCAnaGlnaGx5IHNlbGVjdGl2ZScpKSkgCgpmaWcxIDwtIHNjX3RpbWVfZGYgJT4lIHBsb3RfbHkoeCA9IH5ZZWFyX0VuZGluZywgeSA9IH5gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCwgdHlwZSA9ICdiYXInLAogIGNvbG9yID0gfnVuaV9yYW5rLCBhbHBoYT0wLjgsIGhvdmVydGVtcGxhdGUgPSAnQXZlcmFnZSBEZWJ0L1N0dWRlbnQgKFVTRCk6ICV7eX0gPGV4dHJhPjwvZXh0cmE+Jyxjb2xvcnM9J1B1cnBsZXMnKSAlPiUgCiAgbGF5b3V0KHlheGlzID0gbGlzdCgKICB0aXRsZSA9ICJBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgcGVyIFN0dWRlbnRcbihBZGp1c3RlZCBmb3IgSW5mbGF0aW9uKSIpKQoKZmlnMQoKYGBgCgpDaGxvcm9wbGV0aCBzaG93aW5nIGF2ZXJhZ2Ugc3R1ZGVudCBkZWJ0ICh0aGlzIGlzIG9ubHkgMjAxOSBidXQgSSBoYXZlIGEgZmlsdGVyIGF0IHRoZSBiZWdpbm5pbmcgdGhhdCB3aWxsIGFsbG93IG1lIHRvIGluY29ycG9yYXRlIGEgc2xpZGVyIGZvciB0aGUgeWVhcikuCgpgYGB7ciBTdHVkZW50IERlYnQgbWFwIC0gQ2hsb3JvcGxldGgsIGVjaG89VFJVRSwgZXZhbD1UUlVFIH0KCiMgQWRkaXRpb25zIG9mIFN0YXRlcyBkZiBmcm9tIFRpZ3JpcyBGaWxlIApsaWJyYXJ5KHRpZ3JpcykKc3RhdGVzIDwtIHN0YXRlcyhjYiA9IFRSVUUpCgojIENhbiBjaGFuZ2UgdG8gc2NfdGltZV95ZWFyIApzY190aW1lXzIwMTkgPC0gc2NfdGltZSAlPiUgc3Vic2V0KFllYXJfRW5kaW5nID0gMjAxOSkgJT4lIAogIGdyb3VwX2J5KFNUQUJCUikgJT4lIG11dGF0ZShgQXZlcmFnZSBTdHVkZW50IExvYW5zYD1zdW0oREVCVF9NRE5fU1RVREVOVCxuYS5ybT1UUlVFKS9zdW0oVUdEUyxuYS5ybT1UUlVFKSkgJT4lIGdyb3VwX2J5KFNUQUJCUixgQXZlcmFnZSBTdHVkZW50IExvYW5zYCkgJT4lIHN1bW1hcml6ZSgpCgojIFN0YXRlcyAKc3RhdGVzXzIwMTkgPC0gc3RhdGVzICU+JSAKICBpbm5lcl9qb2luKHNjX3RpbWVfMjAxOSwgYnk9YyhTVFVTUFM9J1NUQUJCUicpKSAKCgpsaWJyYXJ5KGxlYWZsZXQucHJvdmlkZXJzKQpsaWJyYXJ5KGxlYWZsZXQpCiN1c2VkICdzdWNjZXNzJyBtZWFzdXJlcy4gCgpwYWwgPSBjb2xvckZhY3RvcignR3JlZW5zJywgZG9tYWluID0gc3RhdGVzXzIwMTkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApCgpwb3BfcG9wIDwtIHBhc3RlKCJTdGF0ZToiLHN0YXRlc18yMDE5JE5BTUUsIjxici8+IiwKICAgICAgICAgICAgICAgICAiQXZlcmFnZSBTdHVkZW50IExvYW5zIiwiPGJyLz4iLAogICAgICAgICAgICAgICAgICJvZiBTY2hvb2xzIExvY2F0ZWQgaW4gU3RhdGU6IixwYXN0ZSgnJCcscm91bmQoc3RhdGVzXzIwMTkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApKSkKbGlicmFyeShodG1sd2lkZ2V0cykKbGlicmFyeShodG1sdG9vbHMpCnN0YXRlc18yMDE5X3RpdGxlIDwtIHRhZ3MkcCh0YWdzJHN0eWxlKCdwe2NvbG9yOmdyYXk7IGZvbnQtc2l6ZTogMTRweDsgZmFtaWx5OiBzZXJpZn0nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3MkYignQXZlcmFnZSBEZWJ0IEJ5IFN0YXRlICgyMDE5KScpKQoKbGVhZmxldChzdGF0ZXNfMjAxOSkgJT4lIGFkZFByb3ZpZGVyVGlsZXMoIkNhcnRvREIuUG9zaXRyb24iKSAlPiUKICBhZGRQb2x5Z29ucyhmaWxsQ29sb3IgPSB+cGFsKHN0YXRlc18yMDE5JGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSwKICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgd2VpZ2h0ID0gMC41LAogICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC43LCAgCiAgICAgICAgICAgICAgaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0T3B0aW9ucygKICAgICAgICAgICAgICAgIHdlaWdodCA9IDUsCiAgICAgICAgICAgICAgICBjb2xvciA9ICIjNjY2IiwKICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC43LAogICAgICAgICAgICAgICAgYnJpbmdUb0Zyb250ID0gVFJVRSwKICAgICAgICAgICAgICAgICkscG9wdXA9cG9wX3BvcCkgJT4lIGFkZExlZ2VuZChwb3NpdGlvbiA9ICJib3R0b21sZWZ0IiwgY29sb3JzID1jKCIjRURGOEU5IiwiI0JBRTRCMyIsIiM3NEM0NzYiLCIjMzFBMzU0IiwiIzAwNkQyQyIpLCAKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYyhwYXN0ZSgnJCcscm91bmQobWluKHN0YXRlc18yMDE5JGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpLCIgIiwiICIsIiAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnJCcscm91bmQobWF4KHN0YXRlc18yMDE5JGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpKSwKICAgICAgICAgICAgdGl0bGUgPSAiQXZlcmFnZSBTdHVkZW50IExvYW5zIChQZXIgU3R1ZGVudCkiKSAlPiUKICBsZWFmbGV0OjpzZXRWaWV3KC05OC41Nzk1LCAzOS44MjgyLCB6b29tPTMpICU+JSBhZGRDb250cm9sKHN0YXRlc18yMDE5X3RpdGxlLCBwb3NpdGlvbj0ndG9wcmlnaHQnKQo/YWRkTGVnZW5kCmBgYAoKYGBge3J9CmJyZXdlci5wYWwobiA9IDgsIG5hbWUgPSAiUmRZbEduIikKYGBgCgpgYGB7ciBTdHVkZW50IERlYnQgTWFwIC0gcG9pbnRzLCBlY2hvPVRSVUUsIGV2YWw9VFJVRSB9CiMgbGFzdCBlZGl0IHRvIHNjX3RpbWVfMjAxOSBpbiBjaHVuayBhYm92ZSBmb3IgY2hsb3JvcGxldGgKc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSA8LSBzY190aW1lXzIwMTkgJT4lIGRwbHlyOjpyZW5hbWUobGF0ID0gTEFUSVRVREUpICU+JSBkcGx5cjo6cmVuYW1lKGxvbmcgPSBMT05HSVRVREUpICU+JSAKICBkcGx5cjo6cmVuYW1lKHN0YXRlID0gU1RBQkJSKSAlPiUgZmlsdGVyKEFETV9SQVRFIDwgMC4zKSAlPiUgCiAgZHBseXI6Om11dGF0ZSh1bmlfcmFuayA9IGNhc2Vfd2hlbigKICAgIEFETV9SQVRFIDwgMC4wNSB+ICdlbGl0ZScsCiAgICBBRE1fUkFURSA8IDAuMiB+ICdoaWdobHkgc2VsZWN0aXZlJywKICAgIFRSVUUgfiAnc2VsZWN0aXZlJykpCnNjX3RpbWVfMjAxOV9zZWxlY3RpdmUgPC0gc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSAlPiUgc3Vic2V0KERFQlRfTUROICE9J1ByaXZhY3lTdXBwcmVzc2VkJykgJT4lIAogIHRyYW5zZm9ybShERUJUX01ETiA9IGFzLm51bWVyaWMoREVCVF9NRE4pKSAlPiUgCiAgZHBseXI6Om11dGF0ZShERUJUX01ETiA9IGlmZWxzZShpcy5uYShERUJUX01ETiksIDAsIERFQlRfTUROKSkgCgoKCnBhbDEgPSBjb2xvckZhY3RvcihTaG9ydFB1QnVHbiwgZG9tYWluID0gc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSRgdW5pX3JhbmtgLHJldmVyc2U9VFJVRSkKCiNzZXQgcG9wdXBzIApjb250ZW50IDwtIHBhc3RlKCJTY2hvb2wiLHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkSU5TVE5NLCI8YnIvPiIsCiAgICAgICAgICAgICAgICAgIk51bWJlciBvZiBVbmRlcmdyYWRzOiIsc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSRVR0RTLCI8YnIvPiIsCiAgICAgICAgICAgICAgICAgIlNlbGVjdGl2aXR5OiIsIHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkdW5pX3JhbmssIjxici8+IiwKICAgICAgICAgICAgICAgICAiTWVkaWFuIERlYnQ6IixwYXN0ZSgnJCcscm91bmQoc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSRERUJUX01ETiwyKSksIjxici8+IikKc2NfdGltZV8yMDE5X3NlbGVjdGl2ZQpsZWFmbGV0KHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUpICU+JSBhZGRUaWxlcygnaHR0cDovL3tzfS5iYXNlbWFwcy5jYXJ0b2Nkbi5jb20vZGFya19hbGwve3p9L3t4fS97eX0ucG5nJykgJT4lCiAgYWRkQ2lyY2xlcyhjb2wgPSB+cGFsMShzY190aW1lXzIwMTlfc2VsZWN0aXZlJHVuaV9yYW5rKSwKICAgICAgICAgICAgIHJhZGl1cyA9IH5ERUJUX01ETiwKICAgICAgICAgICAgIHBvcHVwID0gY29udGVudCwKICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC43KSAlPiUKICBsZWFmbGV0OjphZGRMZWdlbmQocG9zaXRpb24gPSAiYm90dG9tbGVmdCIscGFsID0gcGFsMSwgdmFsdWVzID0gc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSR1bmlfcmFuaywKICAgICAgICAgICAgdGl0bGUgPSAiQXZlcmFnZSBTdHVkZW50IExvYW5zIChQZXIgU3R1ZGVudCkiKQo/YWRkTGVnZW5kCmBgYApgYGB7cn0Kc2V0d2QoJ34vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZC8nKQpzY190aW1lIDwtIHJlYWRfY3N2KCdzcmMvMjAxMF8yMDE5X3N0dWRlbnRfZGVidC5jc3YnKSAKc2NfdGltZQpgYGAKCgpgYGB7cn0Kc2V0d2QoIn4vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZCIpCnNjX3RpbWUgPC0gcmVhZF9jc3YoJ3NyYy8yMDEwXzIwMTlfc3R1ZGVudF9kZWJ0LmNzdicpIApzY190aW1lPC0gc2NfdGltZSAlPiUgc3Vic2V0KERFQlRfTUROICE9J1ByaXZhY3lTdXBwcmVzc2VkJykgJT4lIAogIHRyYW5zZm9ybShERUJUX01ETiA9IGFzLm51bWVyaWMoREVCVF9NRE4pKSAlPiUgCiAgZHBseXI6Om11dGF0ZShERUJUX01ETiA9IGlmZWxzZShpcy5uYShERUJUX01ETiksIDAsIERFQlRfTUROKSkgJT4lIAogIG11dGF0ZShERUJUX01ETl9TVFVERU5UID0gREVCVF9NRE4qVUdEUykKc2NfdGltZQoKbGlicmFyeShyZXNoYXBlMikKbGlicmFyeShzaGlueSkKdWkgPC0gZmx1aWRQYWdlKAogIHRpdGxlUGFuZWwoIkkgbG92ZSBHcmFwaHMgYWJvdXQgU3R1ZGVudCBEZWJ0IiksCiAgIyBzZWxlY3RJbnB1dCgneWVhcicsCiAgIyAnWWVhcicsCiAgIyBjaG9pY2VzPWMoMjAxMCwyMDExLDIwMTIsMjAxMywyMDE0LDIwMTUsMjAxNiwyMDE3LDIwMTgsMjAxOSkpLCAKICBzbGlkZXJJbnB1dChpbnB1dElkID0gInllYXIiLAogIGxhYmVsID0gIlllYXIiLAogIHZhbHVlID0gYygyMDEwLDIwMTEsMjAxMiwyMDEzLDIwMTQsMjAxNSwyMDE2LDIwMTcsMjAxOCwyMDE5KSksCiAgbGVhZmxldE91dHB1dCgic3R1ZGVudGRlYnRtYXAiKQoKKQoKc2VydmVyIDwtIGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIHNlc3Npb24pewogICMgUmVuZGVyIHBsb3Qgb2YgdG9wIDEwIG1vc3QgcG9wdWxhciBuYW1lcwogICAgc2NfdGltZV9zZWxlY3RpdmUgPC0gcmVhY3RpdmUoe3NjX3RpbWUgJT4lIHN1YnNldChZZWFyX0VuZGluZyA9PSBpbnB1dCR5ZWFyKSAlPiUgCiAgICAgICAgZ3JvdXBfYnkoU1RBQkJSKSAlPiUgbXV0YXRlKGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgPXN1bShERUJUX01ETl9TVFVERU5ULG5hLnJtPVRSVUUpL3N1bShVR0RTLG5hLnJtPVRSVUUpKSAlPiUKICAgICAgICBncm91cF9ieShTVEFCQlIsYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApICU+JSBzdW1tYXJpemUoKX0pCiAgICBsaWJyYXJ5KHRpZ3JpcykKICAgIHN0YXRlcyA8LSBzdGF0ZXMoY2IgPSBUUlVFKQogICAgc3RhdGVzX3llYXIgPC0gcmVhY3RpdmUoe3N0YXRlcyAlPiUgaW5uZXJfam9pbihzY190aW1lX3NlbGVjdGl2ZSgpLCBieT1jKFNUVVNQUz0nU1RBQkJSJykpfSkgCiAgICAKICBvdXRwdXQkc3R1ZGVudGRlYnRtYXAgPC0gcmVuZGVyTGVhZmxldCh7CiAgICBwYWwgPSBjb2xvckZhY3RvcignR3JlZW5zJywgZG9tYWluID0gc3RhdGVzX3llYXIoKSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCkKICAgIHBvcF9wb3AgPC0gcGFzdGUoIlN0YXRlOiIsc3RhdGVzX3llYXIoKSROQU1FLCI8YnIvPiIsCiAgICAgICAgICAgICAgICAgICAgICJBdmVyYWdlIFN0dWRlbnQgTG9hbnMiLCI8YnIvPiIsICJvZiBTY2hvb2xzIExvY2F0ZWQgaW4gU3RhdGU6IiwKICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJyQnLHJvdW5kKHN0YXRlc195ZWFyKCkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApKSkKICAgIAogICAgc2NfdGltZV9zZWxlY3RpdmVfdGl0bGUgPC0gdGFncyRwKHRhZ3Mkc3R5bGUoJ3B7Y29sb3I6Z3JheTsgZm9udC1zaXplOiAxNHB4OyBmYW1pbHk6IHNlcmlmfScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFncyRiKCdBdmVyYWdlIERlYnQgQnkgU3RhdGUgKDIwMTkpJykpCiAgICBsZWFmbGV0KHN0YXRlc195ZWFyKCkpICU+JSBhZGRQcm92aWRlclRpbGVzKCJDYXJ0b0RCLlBvc2l0cm9uIikgJT4lCiAgICAgIGFkZFBvbHlnb25zKGZpbGxDb2xvciA9IH5wYWwoc3RhdGVzX3llYXIoKSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCksCiAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgd2VpZ2h0ID0gMC41LAogICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNywgIAogICAgICAgICAgICAgIGhpZ2hsaWdodCA9IGhpZ2hsaWdodE9wdGlvbnMoCiAgICAgICAgICAgICAgICB3ZWlnaHQgPSA1LAogICAgICAgICAgICAgICAgY29sb3IgPSAiIzY2NiIsCiAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNywKICAgICAgICAgICAgICAgIGJyaW5nVG9Gcm9udCA9IFRSVUUsCiAgICAgICAgICAgICAgICApLHBvcHVwPXBvcF9wb3ApICU+JSBhZGRMZWdlbmQocG9zaXRpb24gPSAiYm90dG9tbGVmdCIsIGNvbG9ycyA9YygiI0VERjhFOSIsIiNCQUU0QjMiLCIjNzRDNDc2IiwiIzMxQTM1NCIsIiMwMDZEMkMiKSwgCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMocGFzdGUoJyQnLHJvdW5kKG1pbihzdGF0ZXNfeWVhcigpJGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpLCIgIiwiICIsIiAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnJCcscm91bmQobWF4KHN0YXRlc195ZWFyKCkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApKSkpLAogICAgICAgICAgICB0aXRsZSA9ICJBdmVyYWdlIFN0dWRlbnQgTG9hbnMgKFBlciBTdHVkZW50KSIpICU+JQogIGxlYWZsZXQ6OnNldFZpZXcoLTk4LjU3OTUsIDM5LjgyODIsIHpvb209MykgJT4lIGFkZENvbnRyb2woc2NfdGltZV9zZWxlY3RpdmVfdGl0bGUsIHBvc2l0aW9uPSd0b3ByaWdodCcpCiAgICB9KQogICAgb2JzZXJ2ZSh7CiAgICBsZWFmbGV0UHJveHkoInN0dWRlbnRkZWJ0bWFwIiwgZGF0YSA9IHN0YXRlc195ZWFyKCkpCiAgfSkgCn0KCnNoaW55QXBwKHVpID0gdWksIHNlcnZlciA9IHNlcnZlcikKCmBgYAoKTm90IGFsbCBzY2hvb2xzIGhhdmUgc2ltaWxhciBhbW91bnRzIG9mIG1lZGlhbiBzdHVkZW50IGRlYnQgYnVyZGVuIChpLmUuLCB1cG9uIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJlcGF5bWVudCBwZXJpb2QpLiBUaGlzIG1hcCBzdW1tYXJpemVzIHRoZSBtZWRpYW4gZGVidCBidXJkZW4gYnkgdGhlIHN0YXRlIHRoYXQgdGhlIHNjaG9vbCBpcyBsb2NhdGVkIGluLiBBcyBzaG93biBpbiB0aGlzIHBsb3QsIHNvbWUgc3RhdGVzIChpbmNsdWRpbmcgc2Nob29scyBpbiBQZW5uc3lsdmFuaWEsIE1pbm5lc290YSwgSWxsaW5vaXMsIGV0Yy4pIHRlbmQgdG8gaGF2ZSB0aGUgaGlnaGVzdCBhdmVyYWdlIG1lZGlhbiBkZWJ0IGJ1cmRlbiBiZXR3ZWVuIHRoZSBzY2hvb2xzIHdpdGhpbi4gVGhlc2Ugc3RhdGVzIGRvIG5vdCBuZWNlc3NhcmlseSBob3VzZSB0aGUgbW9zdCBwcmVzdGlnaW91cyBzY2hvb2xzLiBPbmUgb2YgdGhlIHRoaW5ncyB3ZSBjYW4gc2VlIHdoZW4gZGlzYWdncmVnYXRpbmcgdGhpcyB3YXkgaXMgdGhhdCBsb2NhdGlvbmFsbHkgdGhlcmUgaXMgYSBsb3Qgb2YgZGl2ZXJzaXR5IG9mIHRoZSBzdHVkZW50IGxvYW4gYnVyZGVuIChvbiBhdmVyYWdlKSBnaXZlbiB0byBzdHVkZW50cyBieSBzY2hvb2xzIHdoZW4gZGlzYWdncmVnYXRlZCBhdCB0aGUgc3RhdGUgbGV2ZWwgKHJhbmdpbmcgZnJvbSA0SyB0byAxOEsgVVNEIGluIDIwMTkpCk5vdGUgdGhhdCB3ZSBoYXZlIGFsc28gaW5jbHVkZWQgdGhlIHNoaW55IGludGVyYWN0aXZpdHkgY29tcG9uZW50IGluIHdoaWNoIG9uZSBjYW4gc2VsZWN0IHRoZSB5ZWFyIG9uIHRoZSBzbGlkZXIgdG8gc2VlIHRoZSBzdGF0ZS1sZXZlbCBkZWJ0IG1lZGlhbiBkaXNhZ2dyZWdhdGlvbiBhY3Jvc3MgdGhlIHllYXJzOyB0aGlzIGlzIG5vdCB0aGUgcHJpbWFyeSBmdW5jdGlvbiBidXQgaW5zdGVhZCBpcyBhIGZ1bmN0aW9uYWxpdHkgd2UgYWRkZWQgdG8gYWxsb3cgaW5kaXZpZHVhbHMgdG8gJ2V4cGxvcmUgdGhlIGRhdGEnIGEgYml0LiAKCmBgYHtyfQp1aSA8LSBmbHVpZFBhZ2UoCiAgdGl0bGVQYW5lbCgnVGhlIENvc3Qgb2YgSGlnaGVyIEVkdWNhdGlvbjogQW4gRXhwbG9yYXRpb24gb2YgU3R1ZGVudCBEZWJ0IGluIEFtZXJpY2FuIFVuaXZlcnNpdGllcycpCiAgCikKIApgYGAKCg==
=======
LS0tCnRpdGxlOiAiVmlzdWFsc19EcmFmdF8wNF8xNCIKYXV0aG9yOiAiQ29ubmllIFh1IgpkYXRlOiAiNC8xNC8yMDIxIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Kc2V0d2QoIn4vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZC9zcmMvdmlzdWFscy8iKQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCnNvdXJjZSgib3VydGhlbWUuUiIpCmBgYAoKYGBge3IgcGFja2FnZXMsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KciA9IGdldE9wdGlvbigicmVwb3MiKQpyWyJDUkFOIl0gPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIKb3B0aW9ucyhyZXBvcyA9IHIpCiMgaW5zdGFsbC5wYWNrYWdlcyAoYmFzaWMpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShkcGx5cikpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQoKIyBpbnN0YWxsLnBhY2thZ2VzIChyZWFkaW5nKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoWE1MKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KFJDdXJsKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHJlYWRyKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KCJyZWFkeGwiKSkKCiMgaW5zdGFsbC5wYWNrYWdlcyAodGhlbWVzKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2d0aGVtZXMpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2dyZXBlbCkpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShSQ29sb3JCcmV3ZXIpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkodmlyaWRpcykpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShocmJydGhlbWVzKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHBsb3RseSkpCgoKIyBpbnN0YWxsLnBhY2thZ2VzIChtYXBzKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoUmdvb2dsZU1hcHMpKQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2dtYXApKQpzdXBwcmVzc01lc3NhZ2VzKGluc3RhbGwucGFja2FnZXMoIm1hcHMiKSkKc3VwcHJlc3NNZXNzYWdlcyhpbnN0YWxsLnBhY2thZ2VzKCJ0bWFwIikpICMgaW5zdGFsbCB0aGUgQ1JBTiB2ZXJzaW9uCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeSh0bWFwKSkKc3VwcHJlc3NNZXNzYWdlcyhpbnN0YWxsLnBhY2thZ2VzKCdyZ2VvcycpKQoKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGRldnRvb2xzKSkKIyBMZXQncyBpbnN0YWxsIHRoZSBkZXZlbG9wbWVudCB2ZXJzaW9uIGZyb20gR2l0aHViLiBSdW4KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJyc3R1ZGlvL2xlYWZsZXQiKQpgYGAKCmBgYHtyIGltcG9ydCBnZW5lcmFsIGRhdGEsIGVjaG89VFJVRSwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFNldCB0aGUgV0QgYXMgR3JvdXBfR19IaWdoZXJFZCAKc2V0d2QoIn4vRHJvcGJveCAoQnVzaW5lc3MpL1NwcmluZyAyMDIxL1FNU1MgNTA2MyAtIERhdGEgVmlzdWFsaXphdGlvbiAvR3JvdXBfR19IaWdoZXJFZCIpCgojIFdoaWxlIG91ciBpbml0aWFsIENvbGxlZ2UgU2NvcmVjYXJkIG9ubHkgaW5jbHVkZWQgMjAxOSBpbml0aWFsbHksIEkgd2FzIGFibGUgdG8gcnVuIGEgc2ltcGxlIHB5dGhvbiBzY3JpcHQgdG8gY29uY2F0ZW5hdGUgYW5kIHNlbGVjdCBhIHNtYWxsIG51bWJlciBvZiByZWxldmFudCBjb2x1bW5zIGZvciBvdXIgdmlzdWFsaXphdGlvbiBhbmQgYW5hbHlzaXMuIFRodXMsIGFzIG91ciBmaXJzdCB2aXN1YWxpemF0aW9ucyBvbmx5IHVuY2x1ZGUgMjAxOSwgdGhlIGNvZGUgYmVsb3cgaXMgZm9yIHJlLWZpbHRlcmluZyB0aGUgY29uY2F0ZW5hdGVkIDIwMTAtMjAxOSBkYXRhIGJhY2sgaW50byBzaW1wbHkgMjAxOS4gCgpzY190aW1lIDwtIHJlYWQuY3N2KCcvc3JjLzIwMTBfMjAxOV9zdHVkZW50X2RlYnQuY3N2JykgCnNjIDwtIHNjX3RpbWUgJT4lIGZpbHRlcihZZWFyX0VuZGluZyA9PSAyMDE5KQpzY190aW1lCmxpYnJhcnkoZWR1Y2F0aW9uZGF0YSkKIyBUZXN0IFJ1biB3aXRoIHVzaW5nIGdldF9lZHVjYXRpb25fZGF0YSAKIyBkYXRhIDwtIGdldF9lZHVjYXRpb25fZGF0YShsZXZlbCA9ICJjb2xsZWdlLXVuaXZlcnNpdHkiLAojICAgICBzb3VyY2UgPSAiaXBlZHMiLAojICAgICB0b3BpYyA9ICJkaXJlY3RvcnkiLAojICAgICBmaWx0ZXJzID0gbGlzdCh5ZWFyID0gMjAxOSkpCiMgZGF0YQojIFNjb3JlY2FyZCBkYXRhIC0gMjAxOSAKCiMjIGNoYW5nZSBwcm9qZWN0aW9uIG9mIHNjIGRhdGEKc2MgPC0gc2MgJT4lCiAgZHBseXI6Om11dGF0ZSh1bmlfcmFuayA9IGNhc2Vfd2hlbigKICAgIEFETV9SQVRFIDwgMC4yIH4gJ2hpZ2hseSBzZWxlY3RpdmUvZWxpdGUnLAogICAgQURNX1JBVEUgPCAwLjMgfiAnbW9yZSBzZWxlY3RpdmUnLAogICAgQURNX1JBVEUgPCAwLjUgfiAnc2VsZWN0aXZlJywKICAgIEFETV9SQVRFIDwgMC43IH4gJ2xlc3Mgc2VsZWN0aXZlJywKICAgIFRSVUUgfiAnbm90IHNlbGVjdGl2ZScpKSAlPiUgbXV0YXRlKHVuaV9yYW5rID0gZmFjdG9yKHVuaV9yYW5rLCBsZXZlbHM9Yygnbm90IHNlbGVjdGl2ZScsICdsZXNzIHNlbGVjdGl2ZScsICdzZWxlY3RpdmUnLCAnbW9yZSBzZWxlY3RpdmUnLCAnaGlnaGx5IHNlbGVjdGl2ZS9lbGl0ZScpKSkKYGBgCgojIyBTaW1wbGUgU2NhdHRlcmdyYW0gCgpGaXJzdCB3ZSBhcmUgZ29pbmcgdG8gdHJ5IHRvIHByZXNlbnQgdGhpcyBwYXR0ZXJuIGZvciBkaWZmZXJlbnQgdGllcnMgb2YgdW5pdmVyc2l0aWVzIChhZG1pc3Npb24gcmF0ZSBhcyB3ZWxsIGFzIGRlYnQpCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KIyBSZW1vdmUgUHJpdmFjeVN1cHByZXNzZWQgUmVjb3JkcyBhbmQgdHJhbnNmb3JtIERlYnQgTWVkaWFuIGludG8gYSBudW1lcmljIHZhbHVlIC0gd2UgY2FuIGFsc28gZG8gdGhpcyBvbiB0aGUgbWFpbiBzYyBkZgpzYyRERUJUX01ETltpcy5uYShzYyRERUJUX01ETildIDwtIDA7CgpicmV3ZXIucGFsKG49MTAsIlB1QnVHbiIpClNob3J0UHVCdUduIDwtIGMoIiNEMEQxRTYiLCIjQTZCRERCIiwiIzY3QTlDRiIsIiMzNjkwQzAiLCIjMDI4MThBIikKCm0gPC0gc2MgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogICAgICAgICAgICAgIGdncGxvdCguLCBhZXMoeD1BRE1fUkFURSwgeT1ERUJUX01ETixjb2xvcj11bmlfcmFuaykpICsKICBnZW9tX3BvaW50KHBjaD0yMSkgKwogIGdlb21fc21vb3RoKGNvbG9yPSduYXZ5Jywgc2UgPSBGQUxTRSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9U2hvcnRQdUJ1R24pKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5iYWNrZ3JvdW5kPSBlbGVtZW50X3JlY3QoZmlsbD0id2hpdGUiKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPWMoMCwxMDAwMCwyMDAwMCwzMDAwMCksIGxhYmVscz1jKCcwJywnMTAnLCcyMCcsJzMwJykpICsKICBsYWJzKHg9J0FkbWlzc2lvbnMgUmF0ZScsIHk9J01lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTdHVkZW50IERlYnQgYW5kIEFkbWlzc2lvbnMgUmF0ZScsCiAgICAgICBjb2xvcj0nU2VsZWN0aXZpdHknKQptCmBgYAogIAogIFRoaXMgcGxvdCBzZXRzIG91dCB0byBzaG93IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtZWRpYW4gbG9hbiBhbW91bnQgaW4gMjAxOSBhbmQgdGhlIGFkbWlzc2lvbnMgcmF0ZS4gVGhlIHRyZW5kIHNob3duIGhlcmUgaXMgdGhhdCBhcyB0aGUgYWRtaXNzaW9ucyByYXRlIGdvZXMgdXAgKGkuZS4sIGFzIHNjaG9vbHMgYmVjb21lIGxlc3Mgc2VsZWN0aXZlKSwgc28gZG9lcyBtZWRpYW4gbG9hbiBhbW91bnQgKGF0IGxlYXN0IHVudGlsIHdlIGdvIGZyb20gbGVzcyBzZWxlY3RpdmUgdG8gbm90IHNlbGVjdGl2ZSkuIEJhc2VkIG9uIHRoZSBzY2F0dGVycGxvdCwgaXQgY2FuIGFsc28gYmUgc2VlbiB0aGF0IHRoZSB2YXJpYW5jZSBnb2VzIHVwIGluIHRlcm1zIG9mIG1lZGlhbiBzdHVkZW50IGxvYW4gYW1vdW50IChhbHRob3VnaCBpdCBjYW4gYWxzbyBiZSBzZWVuIHRoYXQgdGhpcyBpcyBwYXJ0aWFsbHkgZHVlIHRvIHRoZSBtdWNoIGxhcmdlciBudW1iZXIgb2Ygc2Nob29scyBpbiB0aGUgbGVzcyBzZWxlY3RpdmUgYnVja2V0cykuICAKICBUaGlzIGlzIHNvbWV3aGF0IGludGVyZXN0aW5nIGJlY2F1c2UgbW9yZSBleGNsdXNpdmUvc2VsZWN0aXZlIHNjaG9vbHMgYXJlIG9uIGF2ZXJhZ2Ugdmlld2VkIGFzIG1vcmUgJ2NvbXBldGl0aXZlJyBhbmQgJ3ByZXN0aWdpb3VzJyAoZS5nLiwgSGFydmFyZCwgU3RhbmZvcmQsIGV0Yy4pOyBhIGdyZWF0IGRlYWwgb2YgZXhpc3RlbnQgbGl0ZXJhdHVyZSBoYXMgbm90ZWQgdGhhdCBzdWNoICdwcmVzdGlnaW91cycgc2Nob29scyBvZnRlbiBlbmQgdXAgYWRtaXR0aW5nIG1vcmUgcGVvcGxlIGZyb20gZWNvbm9taWNhbGx5IHByaXZpbGVnZWQgYmFja2dyb3VuZHMgKG91dHNpZGUgb2YgdGhvc2UgYWRtaXR0ZWQgc3BlY2lmaWNhbGx5IGZvciBkaXZlcnNpdHkpLCBhcyAnbWVyaXQtYmFzZWQnIGFkbWlzc2lvbnMgb2Z0ZW4gY29ycmVsYXRlIHdpdGggYWNjZXNzIHRvIGVjb25vbWljIGFuZCBmaW5hbmNpYWwgcmVzb3VyY2VzLCB3aGljaCBhbGxvdyBmb3IgYWNjZXNzIHRvIHJlc291cmNlcyBoZWxwZnVsIGZvciBjb21wZXRlbmNlIHNpZ25hbGxpbmcsIHN1Y2ggYXMgc3RhbmRhcmRpemVkIHRlc3QgcHJlcCBjb3Vyc2VzLCBzcG9ydHMgYW5kIGFjdGl2aXRpZXMsIGV0YzsgZnVydGhlcm1vcmUsIHN1Y2ggc2Nob29scyBpbmNsdWRlIG1vcmUgZmluYW5jaWFsIHJlc291cmNlcyAoYXMgbW9yZSBwcmVzdGlnaW91cyBzY2hvb2xzIHByb2R1Y2UgYWxtYSBtYXRlcnMgd2l0aCBoaWdoZXIgc29jaW9lY29ub21pYyBvdXRjb21lcykgYW5kIHRodXMgcG90ZW50aWFsbHkgY2FuIGhlbHAgbW9yZSB3aXRoIGZpbmFuY2lhbCBhaWQgYW5kIHNjaG9sYXJzaGlwcy4gCiAgClRoaXMgaXMgYSBkYXRhIHRhYmxlIHNob3dpbmcgdGhlIGJyZWFrZG93biBvZiB0aGUgdW5pdmVyc2l0eSByYW5rcyAoYXMgSSBjaG9zZSB0byByYW5rIHRoZW0pLiBJIHdpbGwgbm90ZSB0aGF0IGZyb20gdGhlIGR0IGFsb25lIHd3ZSBhcmUgc2VlaW5nIGEgZG93bndhcmQgdHJlbmQgaW4gdGhlICdNZWRpYW4gU3R1ZGVudCBMb2FucycgY29sdW1uLiAKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQojIENyZWF0ZSBEYXRhIFRhYmxlIChTdW1tYXJpemVkKSBmb3IgCmxpYnJhcnkoJ3NjYWxlcycpCgpzY19kdCA8LSBzYyAlPiUgc3Vic2V0KERFQlRfTUROICE9J1ByaXZhY3lTdXBwcmVzc2VkJykgJT4lIHRyYW5zZm9ybShERUJUX01ETiA9IGFzLm51bWVyaWMoREVCVF9NRE4pKSAlPiUgZ3JvdXBfYnkodW5pX3JhbmspICU+JSBtdXRhdGUoYE51bWJlciBvZiBVbml2ZXJzaXRpZXNgID0gbigpKSAlPiUgdW5ncm91cCgpICU+JSBtdXRhdGUoREVCVF9NRE5fU1RVREVOVFMgPSBERUJUX01ETipVR0RTKSAlPiUgZ3JvdXBfYnkodW5pX3JhbmspICU+JSBtdXRhdGUoYE1lZGlhbiBTdHVkZW50IExvYW5zYCA9IHBhc3RlKCckJyxyb3VuZChzdW0oREVCVF9NRE5fU1RVREVOVFMsIG5hLnJtPVRSVUUpL3N1bShVR0RTLCBuYS5ybT1UUlVFKSwyKSkpICU+JSAKICBtdXRhdGUoYE1pbiBBY2NlcHRhbmNlIFJhdGVgID0gcGVyY2VudChtaW4oQURNX1JBVEUpKSkgJT4lIG11dGF0ZShgTWF4IEFjY2VwdGFuY2UgUmF0ZWAgPSBwZXJjZW50KG1heChBRE1fUkFURSkpKSAlPiUgdW5ncm91cCgpICU+JSAKICBncm91cF9ieSh1bmlfcmFuayxgTWVkaWFuIFN0dWRlbnQgTG9hbnNgLGBOdW1iZXIgb2YgVW5pdmVyc2l0aWVzYCxgTWluIEFjY2VwdGFuY2UgUmF0ZWAsYE1heCBBY2NlcHRhbmNlIFJhdGVgKSAlPiUgCiAgc3VtbWFyaXplKCkgJT4lIGRwbHlyOjpyZW5hbWUoYFVuaXZlcnNpdHkgU2VsZWN0aXZpdHlgID0gdW5pX3JhbmspCgppbnN0YWxsLnBhY2thZ2VzKCdEVCcpCmxpYnJhcnkoRFQpCnRhYmxlIDwtIGRhdGF0YWJsZShzY19kdCxzdHlsZSA9ICJkZWZhdWx0IixmaWx0ZXIgPSAndG9wJywgIGNhcHRpb24gPSAnVW5pdmVyc2l0aWVzIGFuZCBTZWxlY3Rpdml0eScpCnRhYmxlCgpgYGAKVGhpcyBkYXRhIHRhYmxlIHN1bW1hcml6ZXMgaG93IHdlIGNhdGVnb3JpemVkIG91ciB2YXJpYWJsZSBmb3IgdW5pdmVyc2l0eSBzZWxlY3Rpdml0eSBncm91cGluZyAoZnJvbSB0aGUgQ29sbGVnZSBTY29yZWNhcmQgZmlsZSkuIEl0IGRlc2NyaWJlcyB0aGUgbWVkaWFuIHN0dWRlbnQgbG9hbnMgYW5kIHRoZSBudW1iZXIgb2YgdW5pdmVyc2l0aWVzIGluIGVhY2ggY2F0ZWdvcnkgYXMgb2YgMjAxOSwgYXMgd2VsbCBhcyB0aGUgTWluaW11bSBBY2NlcHRhbmNlIFJhdGUsIGFuZCB0aGUgTWF4aW11bSBBY2NlcHRhbmNlIFJhdGUgdGhyZXNob2xkcy4gCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygndHJlZW1hcCcpCmluc3RhbGwucGFja2FnZXMoJ2hpZ2hjaGFydGVyJykKbGlicmFyeShoaWdoY2hhcnRlcikKbGlicmFyeSh0cmVlbWFwKQoKc2NfZHQgJT4lIGRwbHlyOjptdXRhdGUoRGVzY3JpcHRpb249cGFzdGUoYFVuaXZlcnNpdHkgU2VsZWN0aXZpdHlgLCAnXG4nLGBOdW1iZXIgb2YgVW5pdmVyc2l0aWVzYCwnVW5pdmVyc2l0aWVzJyksIHNlcCA9IlxuIikgJT4lCiAgdHJlZW1hcChpbmRleD0iRGVzY3JpcHRpb24iLAogICAgICAgICAgdlNpemU9Ik51bWJlciBvZiBVbml2ZXJzaXRpZXMiLAogICAgICAgIHR5cGU9ImluZGV4IiwKICAgICAgICBmb250c2l6ZS5sYWJlbHM9YygxMiwgOCksIAogICAgICAgIHBhbGV0dGUgPSAgdmlyaWRpcyg1KSwKICAgICAgICBib3JkZXIuY29sPSJ3aGl0ZSIsCiAgICAgICAgdGl0bGUgPSAnVW5pdmVyc2l0aWVzIGFuZCBTZWxlY3Rpdml0eScpCmBgYAoKICBUaGUgdHJlZW1hcCBhYm92ZSB2aXN1YWxpemVzIGFuZCBzdW1tYXJpemVzIHRoZSBzZWxlY3Rpdml0eSBncm91cGluZyBsYWJlbCBhbmQgdW5pdmVyc2l0eSBjb3VudHMgd2l0aGluIGVhY2ggb2YgdGhlIGNhdGVnb3JpY2FsIHNlbGVjdGl2aXR5IGdyb3VwaW5ncy4gQXMgc2hvd24gYWJvdmUsIHRoZSB2YXN0IG1ham9yaXR5IG9mIHNjaG9vbHMgaW4gb3VyIGRhdGFzZXQgd2VyZSAnbm90IHNlbGVjdGl2ZScgb3IgJ2xlc3Mgc2VsZWN0aXZlJzsgaG93ZXZlciwgbWFueSBvZiBvdXIgYW5hbHlzZXMgZm9jdXMgb24gdGhlIHNtYWxsZXIgY2F0ZWdvcmllcyAocGFydGljdWxhcmx5IHNlbGVjdGl2ZSB0byBoaWdobHkgc2VsZWN0aXZlL2VsaXRlKSwgYmVjYXVzZSB0aGVzZSBjYXRlZ29yaWVzIGhhdmUgbW9yZSB3aXRoaW4tZ3JvdXAgaG9tb2dlbmVpdHkgYW5kIGZ1cnRoZXJtb3JlIGFyZSBtb3JlIGludGVyZXN0aW5nIHRvIG91ciBmb2NhbCBxdWVzdGlvbnMuIAoKIyMgU2NhdHRlcmdyYW0gYXMgVmlvbGluIFBsb3QKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQptIDwtIHNjICU+JSBzdWJzZXQoREVCVF9NRE4gIT0nUHJpdmFjeVN1cHByZXNzZWQnKSAlPiUgdHJhbnNmb3JtKERFQlRfTUROID0gYXMubnVtZXJpYyhERUJUX01ETikpICU+JSAKICBnZ3Bsb3QoLiwgYWVzKHg9dW5pX3JhbmssIHk9REVCVF9NRE4pKSArCiAgZ2VvbV92aW9saW4oYWVzKGZpbGw9dW5pX3JhbmssY29sb3I9dW5pX3JhbmspKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4yKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9U2hvcnRQdUJ1R24pICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1TaG9ydFB1QnVHbikgKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5iYWNrZ3JvdW5kPSBlbGVtZW50X3JlY3QoZmlsbD0id2hpdGUiKSkrCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9YygwLDEwMDAwLDIwMDAwLDMwMDAwKSwgbGFiZWxzPWMoJzAnLCcxMCcsJzIwJywnMzAnKSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoJ25vdFxuc2VsZWN0aXZlXG4oPjcwJSknLCdsZXNzXG5zZWxlY3RpdmVcbig1MCUtNzAlKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0aXZlXG4oMzAlLTUwJSknLCdtb3JlXG5zZWxlY3RpdmVcbigyMCUtMzAlKScsJ2hpZ2hseVxuc2VsZWN0aXZlXG4oNSUtMjAlKScsJ2VsaXRlXG4oPDUlKScpKSArCgogIGxhYnMoeD0nU2VsZWN0aXZpdHlcbihhZG1pc3Npb24gcmF0ZSB0aHJlc2hvbGRzKScsIHk9J01lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTZWxlY3RpdmUgU2Nob29scyBhbmQgU3R1ZGVudCBEZWJ0JywKICAgICAgIGNvbG9yPScnLGZpbGw9JycpCm0KYGBgClNob3dpbmcgdGhlIHByZXZpb3VzIHNjYXR0ZXJncmFtIHNwZWNpZmljYWxseSBhcyB2aW9saW4gcGxvdHMKCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KaXBlZHMxNSA8LSBnZXRfZWR1Y2F0aW9uX2RhdGEobGV2ZWwgPSAiY29sbGVnZS11bml2ZXJzaXR5IiwKICAgIHNvdXJjZSA9ICJpcGVkcyIsCiAgICB0b3BpYyA9ICJncmFkLXJhdGVzLXBlbGwiLAogICAgZmlsdGVycyA9IGxpc3QoeWVhciA9IDIwMTUpKQppcGVkczE1CmBgYAoKCiMjIFN0dWRlbnQgRGVidCBvdmVyIFRpbWUKCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KCiNQcm9jZXNzIHRoZSBkYXRhIApzY190aW1lIDwtIHJlYWRfY3N2KCcyMDEwXzIwMTlfc3R1ZGVudF9kZWJ0LmNzdicpIAoKc2NfdGltZTwtIHNjX3RpbWUgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSAKICB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoREVCVF9NRE4gPSBpZmVsc2UoaXMubmEoREVCVF9NRE4pLCAwLCBERUJUX01ETikpCgpgYGAKCgpgYGB7ciwgZWNobz1UUlVFLCBldmFsPVRSVUV9CiNQcm9jZXNzIHRoZSBkYXRhIApzZXR3ZCgifi9Ecm9wYm94IChCdXNpbmVzcykvU3ByaW5nIDIwMjEvUU1TUyA1MDYzIC0gRGF0YSBWaXN1YWxpemF0aW9uIC9Hcm91cF9HX0hpZ2hlckVkIikKc2NfdGltZSA8LSByZWFkX2Nzdignc3JjLzIwMTBfMjAxOV9zdHVkZW50X2RlYnQuY3N2JykgCnNjX3RpbWU8LSBzY190aW1lICU+JSBzdWJzZXQoREVCVF9NRE4gIT0nUHJpdmFjeVN1cHByZXNzZWQnKSAlPiUgCiAgdHJhbnNmb3JtKERFQlRfTUROID0gYXMubnVtZXJpYyhERUJUX01ETikpICU+JSAKICBkcGx5cjo6bXV0YXRlKERFQlRfTUROID0gaWZlbHNlKGlzLm5hKERFQlRfTUROKSwgMCwgREVCVF9NRE4pKSAlPiUgCiAgbXV0YXRlKERFQlRfTUROX1NUVURFTlQgPSBERUJUX01ETipVR0RTKQpzY190aW1lCgpzdW0oc2NfdGltZSRVR0RTLG5hLnJtPVRSVUUpCmBgYAoKQmVsb3cgaXMgYW4gaW50ZXJhY3RpdmUgbGluZSBncmFwaCAoMjAxMC0yMDE5KSB3aGljaCBkZXRhaWxzIHRoZSB0cmVuZHMgaW4gc3R1ZGVudCBkZWJ0IG92ZXIgdGhlIHllYXJzLiAKYGBge3IsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQojIENQSSBJbmZsYXRpb24gUmF0ZXMgLSBHb3QgQXZlcmFnZSBZZWFybHkgSW5mbGF0aW9uIFJhdGUgZm9yIFNjYWxpbmcgZm9yIFN0dWRlbnQgRGVidCAKaW5zdGFsbC5wYWNrYWdlcygncXVhbnRtb2QnKQpsaWJyYXJ5KHF1YW50bW9kKQpnZXRTeW1ib2xzKCJDUElBVUNTTCIsIHNyYz0nRlJFRCcpCmF2Zy5jcGkgPC0gYXBwbHkueWVhcmx5KENQSUFVQ1NMLCBtZWFuKQpjZiA8LSBhcy5kYXRhLmZyYW1lKGF2Zy5jcGkvYXMubnVtZXJpYyhhdmcuY3BpWycyMDA5J10pKSAKY2YkWWVhcl9FbmRpbmcgPC0gZm9ybWF0KGFzLkRhdGUocm93Lm5hbWVzKGNmKSwgZm9ybWF0PSIlWS0lbS0lZCIpLCIlWSIpCgojIE1lcmdlZCBmb3IgSW5mbGF0aW9uIApzY190aW1lX2RmIDwtIHNjX3RpbWUgJT4lIGdyb3VwX2J5KGBZZWFyX0VuZGluZ2ApICU+JSBtdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCA9IHN1bShERUJUX01ETl9TVFVERU5ULG5hLnJtPVRSVUUpL3N1bShVR0RTLG5hLnJtPVRSVUUpKSAlPiUgdW5ncm91cCgpICU+JSAKICBkcGx5cjo6bXV0YXRlKHVuaV9yYW5rID0gY2FzZV93aGVuKAogICAgQURNX1JBVEUgPCAwLjIgfiAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScsCiAgICBBRE1fUkFURSA8IDAuMyB+ICdtb3JlIHNlbGVjdGl2ZScsCiAgICBBRE1fUkFURSA8IDAuNSB+ICdzZWxlY3RpdmUnLAogICAgQURNX1JBVEUgPCAwLjcgfiAnbGVzcyBzZWxlY3RpdmUnLAogICAgVFJVRSB+ICdub3Qgc2VsZWN0aXZlJykpICU+JQogIG11dGF0ZSh1bmlfcmFuayA9IGZhY3Rvcih1bmlfcmFuaywgbGV2ZWxzPWMoJ25vdCBzZWxlY3RpdmUnLCAnbGVzcyBzZWxlY3RpdmUnLCAnc2VsZWN0aXZlJywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9yZSBzZWxlY3RpdmUnLCAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScpKSkgJT4lCiAgZ3JvdXBfYnkodW5pX3JhbmssWWVhcl9FbmRpbmcpICU+JSAKICBtdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAoYnkgU2VsZWN0aXZpdHkpYCA9IHN1bShERUJUX01ETl9TVFVERU5ULG5hLnJtPVRSVUUpL3N1bShVR0RTLG5hLnJtPVRSVUUpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShgWWVhcl9FbmRpbmdgLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAsCiAgICAgICAgICAgdW5pX3JhbmssYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCkgJT4lIHN1bW1hcml6ZSgpICU+JSAKICBtZXJnZShjZikgJT4lIAogIG11dGF0ZShgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCA9IGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAvCiAgICAgICAgICAgQ1BJQVVDU0wpICU+JSAKICBtdXRhdGUoYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWAgPSBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgLwogICAgICAgICAgIENQSUFVQ1NMKQoKc2NfZGYgPC0gc2NfdGltZV9kZiAlPiUgZ3JvdXBfYnkoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCxgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gQ29tcG9zaXRlYCxZZWFyX0VuZGluZykgJT4lIHN1bW1hcml6ZSgpICU+JSBtdXRhdGUodW5pX3Jhbms9J25hdGlvbmFsIGF2ZXJhZ2UnKSAlPiUgbXV0YXRlKGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnRgPWBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgKSAlPiUgZHBseXI6Om11dGF0ZShgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgID0gYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCkgJT4lIG1lcmdlKGNmKSAlPiUgc2VsZWN0KFllYXJfRW5kaW5nLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAsIHVuaV9yYW5rLCBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgLCBDUElBVUNTTCwgYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidGAsYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWApCnNjX3RpbWVfZGYgPC0gc2NfdGltZV9kZiAlPiUgcmJpbmQoc2NfZGYpICU+JSBtdXRhdGUodW5pX3JhbmsgPSBmYWN0b3IodW5pX3JhbmssIGxldmVscz1jKCduYXRpb25hbCBhdmVyYWdlJywnbm90IHNlbGVjdGl2ZScsICdsZXNzIHNlbGVjdGl2ZScsICdzZWxlY3RpdmUnLCAnbW9yZSBzZWxlY3RpdmUnLCAnZWxpdGUvaGlnaGx5IHNlbGVjdGl2ZScpKSkgJT4lIAogIG11dGF0ZShgR3JvdXAgTGV2ZWxgID0gaWZlbHNlKHVuaV9yYW5rID09ICduYXRpb25hbCBhdmVyYWdlJywgJ05hdGlvbmFsJywnU2VsZWN0aXZpdHknKSkKc2NfZGYKc2NfdGltZV9kZgoKCnAgPC0gc2NfdGltZV9kZiAlPiUgCiAgZ2dwbG90KC4sYWVzKHg9WWVhcl9FbmRpbmcseT1gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCwgY29sb3I9dW5pX3JhbmspKSArIAogIGdlb21fbGluZShhZXMobGluZXR5cGU9YEdyb3VwIExldmVsYCkpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdncmV5JywiI0QwRDFFNiIsIiNBNkJEREIiLCIjNjdBOUNGIiwiIzM2OTBDMCIsIiMwMjgxOEEiKSkrCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiKSkrCiAgdGhlbWUoCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmJhY2tncm91bmQ9IGVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHJvdW5kKHNlcShtaW4oc2NfdGltZSRZZWFyX0VuZGluZyksIG1heChzY190aW1lJFllYXJfRW5kaW5nKSwgYnkgPSAyKSwxKSkgKwogIGxhYnMoeD0nJywgeT0nSW5mbGF0aW9uLUFkanVzdGVkIE1lZGlhbiBMb2FuIEFtb3VudCBwZXIgU3R1ZGVudFxuKHRob3VzYW5kcyknLCAKICAgICAgIHRpdGxlPSdTdHVkZW50IERlYnQgSGFzIEJlZW4gUmlzaW5nIE92ZXIgVGhlIFllYXJzJywKICAgICAgIGNvbG9yPScnLGZpbGw9JycsZ3JvdXA9JycsbGluZXR5cGU9JycpCmdncGxvdGx5KHApCgoKYGBgCgogIEJldHdlZW4gMjAxMCBhbmQgMjAxOCwgdGhlIG1lZGlhbiBsb2FuIGFtb3VudCBwZXIgc3R1ZGVudCBpbmNyZWFzZWQgYnkgMjAwMC00MDAwKyBVU0QgKGluZmxhdGlvbi1hZGp1c3RlZCkgLSBuYXRpb25hbGx5LCB0aGUgbWVkaWFuIHN0dWRlbnQgbG9hbiBhbW91bnQgaW5jcmVhc2VkIGJ5IDE5JS4gV2hlbiBvbmUgZGlzYWdncmVnYXRlcyB1bml2ZXJzaXRpZXMgYnkgc2VsZWN0aXZpdHksIHdlIHNlZSB0aGUgc2FtZSAqb3ZlcmFsbCogdHJlbmQgb3ZlciB0aW1lIChpLmUuLCB0aGVyZSBpcyBhIGZhaXIgYW1vdW50IG9mIGluY3JlYXNlIGR1cmluZyB0aGUgcGVyaW9kIGluIHRlcm1zIG9mIGF2ZXJhZ2Ugc3R1ZGVudCBsb2FucyB0aGF0IHN0dWRlbnRzIGxlYXZlIHdpdGggdXBvbiBlbnRlcmluZyByZXBheW1lbnQpOyBob3dldmVyLCBzb21lIHNlbGVjdGl2aXR5IGdyb3VwcyBpbmNyZWFzZWQgbW9yZSBkcmFtYXRpY2FsbHkgdGhhbiBvdGhlcnMgKGUuZy4sICdNb3JlIFNlbGVjdGl2ZScgb3Igc2Nob29scyB3aXRoIDIwLTMwJSBhY2NlcHRhbmNlIHJhdGVzIGFwcGVhcmVkIHRvIGluY3JlYXNlIGdyZWF0bHkgaW4gdGVybXMgb2Ygc3R1ZGVudCBkZWJ0IHByaW5jaXBhbCBiZXR3ZWVuIDIwMTUgYW5kIDIwMTcsIGJ1dCB0aGlzIGFtb3VudCBkZWNsaW5lZCBhIGJpdCBhZ2FpbiBpbiAyMDE4KSBhbmQgZGlmZmVyZW50IHNlbGVjdGl2aXR5IGdyb3VwcyBkZWNyZWFzZWQgaW4gbWVkaWFuIHN0dWRlbnQgZGVidCBvdmVyIHRpbWUgKGxlc3Mgc2VsZWN0aXZlOyBzZWxlY3RpdmUgc2Nob29scyBzZWVtZWQgdG8gZGVjcmVhc2UgaW4gbWVkaWFuIGRlYnQgZm9sbG93aW5nIDIwMTQpLiAgCiAgVG8gbG9vayBhdCBob3cgbWVkaWFuIHN0dWRlbnQgZGVidCBoYXMgY2hhbmdlZCBlaXRoZXIgYnkgb25seSBuYXRpb25hbCBhdmVyYWdlIG9yIHRvIGxvb2sgYXQgc3BlY2lmaWMgJ3NlbGVjdGl2aXR5JyBidWNrZXRzLCBvbmUgY2FuIHNpbXBseSBjbGljayB0byByZW1vdmUgdGhlIHJlbWFpbmluZyBsaW5lcyBpbiB0aGUgcGxvdC4gCgpUaGUgZm9sbG93aW5nIGlzIChpbnN0ZWFkKSBhIGJhciBncmFwaCB3aXRoIGZld2VyICd1bml2ZXJzaXR5IHNlbGVjdGl2aXR5JyBidWNrZXRzLiAKYGBge3J9CnNjX3RpbWVfZGYgPC0gc2NfdGltZSAlPiUgZ3JvdXBfYnkoYFllYXJfRW5kaW5nYCkgJT4lIG11dGF0ZShgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gTmF0aW9uYWxgID0gc3VtKERFQlRfTUROX1NUVURFTlQsbmEucm09VFJVRSkvc3VtKFVHRFMsbmEucm09VFJVRSkpICU+JSB1bmdyb3VwKCkgJT4lIAogIGRwbHlyOjptdXRhdGUodW5pX3JhbmsgPSBjYXNlX3doZW4oCiAgICBBRE1fUkFURSA8IDAuMiB+ICdoaWdobHkgc2VsZWN0aXZlJywKICAgIEFETV9SQVRFIDwgMC41IH4gJ21vZGVyYXRlbHkgc2VsZWN0aXZlJywKICAgIFRSVUUgfiAnbGVzcy9ub3QgYXQgYWxsIHNlbGVjdGl2ZScpKSAlPiUKICBtdXRhdGUodW5pX3JhbmsgPSBmYWN0b3IodW5pX3JhbmssIGxldmVscz1jKCdsZXNzL25vdCBhdCBhbGwgc2VsZWN0aXZlJywgJ21vZGVyYXRlbHkgc2VsZWN0aXZlJywgJ2hpZ2hseSBzZWxlY3RpdmUnKSkpICU+JQogIGdyb3VwX2J5KHVuaV9yYW5rLFllYXJfRW5kaW5nKSAlPiUgCiAgbXV0YXRlKGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgKGJ5IFNlbGVjdGl2aXR5KWAgPSBzdW0oREVCVF9NRE5fU1RVREVOVCxuYS5ybT1UUlVFKS9zdW0oVUdEUyxuYS5ybT1UUlVFKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoYFllYXJfRW5kaW5nYCxgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLAogICAgICAgICAgIHVuaV9yYW5rLGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGApICU+JSBzdW1tYXJpemUoKSAlPiUgCiAgbWVyZ2UoY2YpICU+JSAKICBtdXRhdGUoYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidGAgPSBgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLwogICAgICAgICAgIENQSUFVQ1NMKSAlPiUgCiAgbXV0YXRlKGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgID0gYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYC8KICAgICAgICAgICBDUElBVUNTTCkKCnNjX2RmIDwtIHNjX3RpbWVfZGYgJT4lIGdyb3VwX2J5KGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGAsYEFkanVzdGVkIEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIENvbXBvc2l0ZWAsWWVhcl9FbmRpbmcpICU+JSBzdW1tYXJpemUoKSAlPiUgbXV0YXRlKHVuaV9yYW5rPSduYXRpb25hbCBhdmVyYWdlJykgJT4lIG11dGF0ZShgQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YD1gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IC0gQ29tcG9zaXRlYCkgJT4lIGRwbHlyOjptdXRhdGUoYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAoYnkgU2VsZWN0aXZpdHkpYCA9IGBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBOYXRpb25hbGApICU+JSBtZXJnZShjZikgJT4lIHNlbGVjdChZZWFyX0VuZGluZyxgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0IChieSBTZWxlY3Rpdml0eSlgLCB1bmlfcmFuaywgYEF2ZXJhZ2UgQW5udWFsIFN0dWRlbnQgRGVidCAtIE5hdGlvbmFsYCwgQ1BJQVVDU0wsIGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnRgLGBBZGp1c3RlZCBBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgLSBDb21wb3NpdGVgKQpzY190aW1lX2RmIDwtIHNjX3RpbWVfZGYgJT4lIHJiaW5kKHNjX2RmKSAlPiUgbXV0YXRlKHVuaV9yYW5rID0gZmFjdG9yKHVuaV9yYW5rLCBsZXZlbHM9YygnbmF0aW9uYWwgYXZlcmFnZScsJ2xlc3Mvbm90IGF0IGFsbCBzZWxlY3RpdmUnLCAnbW9kZXJhdGVseSBzZWxlY3RpdmUnLCAnaGlnaGx5IHNlbGVjdGl2ZScpKSkgCgpmaWcxIDwtIHNjX3RpbWVfZGYgJT4lIHBsb3RfbHkoeCA9IH5ZZWFyX0VuZGluZywgeSA9IH5gQWRqdXN0ZWQgQXZlcmFnZSBBbm51YWwgU3R1ZGVudCBEZWJ0YCwgdHlwZSA9ICdiYXInLAogIGNvbG9yID0gfnVuaV9yYW5rLCBhbHBoYT0wLjgsIGhvdmVydGVtcGxhdGUgPSAnQXZlcmFnZSBEZWJ0L1N0dWRlbnQgKFVTRCk6ICV7eX0gPGV4dHJhPjwvZXh0cmE+Jyxjb2xvcnM9J1B1cnBsZXMnKSAlPiUgCiAgbGF5b3V0KHlheGlzID0gbGlzdCgKICB0aXRsZSA9ICJBdmVyYWdlIEFubnVhbCBTdHVkZW50IERlYnQgcGVyIFN0dWRlbnRcbihBZGp1c3RlZCBmb3IgSW5mbGF0aW9uKSIpKQoKZmlnMQoKYGBgCgpDaGxvcm9wbGV0aCBzaG93aW5nIGF2ZXJhZ2Ugc3R1ZGVudCBkZWJ0ICh0aGlzIGlzIG9ubHkgMjAxOSBidXQgSSBoYXZlIGEgZmlsdGVyIGF0IHRoZSBiZWdpbm5pbmcgdGhhdCB3aWxsIGFsbG93IG1lIHRvIGluY29ycG9yYXRlIGEgc2xpZGVyIGZvciB0aGUgeWVhcikuCgpgYGB7ciBTdHVkZW50IERlYnQgbWFwIC0gQ2hsb3JvcGxldGgsIGVjaG89VFJVRSwgZXZhbD1UUlVFIH0KCiMgQWRkaXRpb25zIG9mIFN0YXRlcyBkZiBmcm9tIFRpZ3JpcyBGaWxlIApsaWJyYXJ5KHRpZ3JpcykKCnN0YXRlcyA8LSBzdGF0ZXMoY2IgPSBUUlVFKQoKIyBDYW4gY2hhbmdlIHRvIHNjX3RpbWVfeWVhciAKc2NfdGltZV8yMDE5IDwtIHNjX3RpbWUgJT4lIHN1YnNldChZZWFyX0VuZGluZyA9IDIwMTkpICU+JSAKICBncm91cF9ieShTVEFCQlIpICU+JSBtdXRhdGUoYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2A9c3VtKERFQlRfTUROX1NUVURFTlQsbmEucm09VFJVRSkvc3VtKFVHRFMsbmEucm09VFJVRSkpICU+JSBncm91cF9ieShTVEFCQlIsYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApICU+JSBzdW1tYXJpemUoKQoKIyBTdGF0ZXMgCnN0YXRlc18yMDE5IDwtIHN0YXRlcyAlPiUgCiAgaW5uZXJfam9pbihzY190aW1lXzIwMTksIGJ5PWMoU1RVU1BTPSdTVEFCQlInKSkgCgoKbGlicmFyeShsZWFmbGV0LnByb3ZpZGVycykKbGlicmFyeShsZWFmbGV0KQojdXNlZCAnc3VjY2VzcycgbWVhc3VyZXMuIAoKcGFsID0gY29sb3JGYWN0b3IoJ0dyZWVucycsIGRvbWFpbiA9IHN0YXRlc18yMDE5JGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKQoKcG9wX3BvcCA8LSBwYXN0ZSgiU3RhdGU6IixzdGF0ZXNfMjAxOSROQU1FLCI8YnIvPiIsCiAgICAgICAgICAgICAgICAgIkF2ZXJhZ2UgU3R1ZGVudCBMb2FucyIsIjxici8+IiwKICAgICAgICAgICAgICAgICAib2YgU2Nob29scyBMb2NhdGVkIGluIFN0YXRlOiIscGFzdGUoJyQnLHJvdW5kKHN0YXRlc18yMDE5JGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpCmxpYnJhcnkoaHRtbHdpZGdldHMpCmxpYnJhcnkoaHRtbHRvb2xzKQpzdGF0ZXNfMjAxOV90aXRsZSA8LSB0YWdzJHAodGFncyRzdHlsZSgncHtjb2xvcjpncmF5OyBmb250LXNpemU6IDE0cHg7IGZhbWlseTogc2VyaWZ9JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdzJGIoJ0F2ZXJhZ2UgRGVidCBCeSBTdGF0ZSAoMjAxOSknKSkKCmxlYWZsZXQoc3RhdGVzXzIwMTkpICU+JSBhZGRQcm92aWRlclRpbGVzKCJDYXJ0b0RCLlBvc2l0cm9uIikgJT4lCiAgYWRkUG9seWdvbnMoZmlsbENvbG9yID0gfnBhbChzdGF0ZXNfMjAxOSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCksCiAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgIHdlaWdodCA9IDAuNSwKICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNywgIAogICAgICAgICAgICAgIGhpZ2hsaWdodCA9IGhpZ2hsaWdodE9wdGlvbnMoCiAgICAgICAgICAgICAgICB3ZWlnaHQgPSA1LAogICAgICAgICAgICAgICAgY29sb3IgPSAiIzY2NiIsCiAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNywKICAgICAgICAgICAgICAgIGJyaW5nVG9Gcm9udCA9IFRSVUUsCiAgICAgICAgICAgICAgICApLHBvcHVwPXBvcF9wb3ApICU+JSBhZGRMZWdlbmQocG9zaXRpb24gPSAiYm90dG9tbGVmdCIsIGNvbG9ycyA9YygiI0VERjhFOSIsIiNCQUU0QjMiLCIjNzRDNDc2IiwiIzMxQTM1NCIsIiMwMDZEMkMiKSwgCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMocGFzdGUoJyQnLHJvdW5kKG1pbihzdGF0ZXNfMjAxOSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCkpKSwiICIsIiAiLCIgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJyQnLHJvdW5kKG1heChzdGF0ZXNfMjAxOSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCkpKSksCiAgICAgICAgICAgIHRpdGxlID0gIkF2ZXJhZ2UgU3R1ZGVudCBMb2FucyAoUGVyIFN0dWRlbnQpIikgJT4lCiAgbGVhZmxldDo6c2V0VmlldygtOTguNTc5NSwgMzkuODI4Miwgem9vbT0zKSAlPiUgYWRkQ29udHJvbChzdGF0ZXNfMjAxOV90aXRsZSwgcG9zaXRpb249J3RvcHJpZ2h0JykKP2FkZExlZ2VuZApgYGAKCmBgYHtyfQpicmV3ZXIucGFsKG4gPSA4LCBuYW1lID0gIlJkWWxHbiIpCmBgYAoKYGBge3IgU3R1ZGVudCBEZWJ0IE1hcCAtIHBvaW50cywgZWNobz1UUlVFLCBldmFsPVRSVUUgfQojIGxhc3QgZWRpdCB0byBzY190aW1lXzIwMTkgaW4gY2h1bmsgYWJvdmUgZm9yIGNobG9yb3BsZXRoCnNjX3RpbWVfMjAxOV9zZWxlY3RpdmUgPC0gc2NfdGltZV8yMDE5ICU+JSBkcGx5cjo6cmVuYW1lKGxhdCA9IExBVElUVURFKSAlPiUgZHBseXI6OnJlbmFtZShsb25nID0gTE9OR0lUVURFKSAlPiUgCiAgZHBseXI6OnJlbmFtZShzdGF0ZSA9IFNUQUJCUikgJT4lIGZpbHRlcihBRE1fUkFURSA8IDAuMykgJT4lIAogIGRwbHlyOjptdXRhdGUodW5pX3JhbmsgPSBjYXNlX3doZW4oCiAgICBBRE1fUkFURSA8IDAuMDUgfiAnZWxpdGUnLAogICAgQURNX1JBVEUgPCAwLjIgfiAnaGlnaGx5IHNlbGVjdGl2ZScsCiAgICBUUlVFIH4gJ3NlbGVjdGl2ZScpKQpzY190aW1lXzIwMTlfc2VsZWN0aXZlIDwtIHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSAKICB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoREVCVF9NRE4gPSBpZmVsc2UoaXMubmEoREVCVF9NRE4pLCAwLCBERUJUX01ETikpIAoKCgpwYWwxID0gY29sb3JGYWN0b3IoU2hvcnRQdUJ1R24sIGRvbWFpbiA9IHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkYHVuaV9yYW5rYCxyZXZlcnNlPVRSVUUpCgojc2V0IHBvcHVwcyAKY29udGVudCA8LSBwYXN0ZSgiU2Nob29sIixzY190aW1lXzIwMTlfc2VsZWN0aXZlJElOU1ROTSwiPGJyLz4iLAogICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgVW5kZXJncmFkczoiLHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkVUdEUywiPGJyLz4iLAogICAgICAgICAgICAgICAgICJTZWxlY3Rpdml0eToiLCBzY190aW1lXzIwMTlfc2VsZWN0aXZlJHVuaV9yYW5rLCI8YnIvPiIsCiAgICAgICAgICAgICAgICAgIk1lZGlhbiBEZWJ0OiIscGFzdGUoJyQnLHJvdW5kKHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkREVCVF9NRE4sMikpLCI8YnIvPiIpCnNjX3RpbWVfMjAxOV9zZWxlY3RpdmUKbGVhZmxldChzY190aW1lXzIwMTlfc2VsZWN0aXZlKSAlPiUgYWRkVGlsZXMoJ2h0dHA6Ly97c30uYmFzZW1hcHMuY2FydG9jZG4uY29tL2RhcmtfYWxsL3t6fS97eH0ve3l9LnBuZycpICU+JQogIGFkZENpcmNsZXMoY29sID0gfnBhbDEoc2NfdGltZV8yMDE5X3NlbGVjdGl2ZSR1bmlfcmFuayksCiAgICAgICAgICAgICByYWRpdXMgPSB+REVCVF9NRE4sCiAgICAgICAgICAgICBwb3B1cCA9IGNvbnRlbnQsCiAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNykgJT4lCiAgbGVhZmxldDo6YWRkTGVnZW5kKHBvc2l0aW9uID0gImJvdHRvbWxlZnQiLHBhbCA9IHBhbDEsIHZhbHVlcyA9IHNjX3RpbWVfMjAxOV9zZWxlY3RpdmUkdW5pX3JhbmssCiAgICAgICAgICAgIHRpdGxlID0gIkF2ZXJhZ2UgU3R1ZGVudCBMb2FucyAoUGVyIFN0dWRlbnQpIikKP2FkZExlZ2VuZApgYGAKYGBge3J9CnNldHdkKCd+L0Ryb3Bib3ggKEJ1c2luZXNzKS9TcHJpbmcgMjAyMS9RTVNTIDUwNjMgLSBEYXRhIFZpc3VhbGl6YXRpb24gL0dyb3VwX0dfSGlnaGVyRWQvJykKc2NfdGltZSA8LSByZWFkX2Nzdignc3JjLzIwMTBfMjAxOV9zdHVkZW50X2RlYnQuY3N2JykgCnNjX3RpbWUKYGBgCgoKYGBge3J9CnNldHdkKCJ+L0Ryb3Bib3ggKEJ1c2luZXNzKS9TcHJpbmcgMjAyMS9RTVNTIDUwNjMgLSBEYXRhIFZpc3VhbGl6YXRpb24gL0dyb3VwX0dfSGlnaGVyRWQiKQpzY190aW1lIDwtIHJlYWRfY3N2KCdzcmMvMjAxMF8yMDE5X3N0dWRlbnRfZGVidC5jc3YnKSAKc2NfdGltZTwtIHNjX3RpbWUgJT4lIHN1YnNldChERUJUX01ETiAhPSdQcml2YWN5U3VwcHJlc3NlZCcpICU+JSAKICB0cmFuc2Zvcm0oREVCVF9NRE4gPSBhcy5udW1lcmljKERFQlRfTUROKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoREVCVF9NRE4gPSBpZmVsc2UoaXMubmEoREVCVF9NRE4pLCAwLCBERUJUX01ETikpICU+JSAKICBtdXRhdGUoREVCVF9NRE5fU1RVREVOVCA9IERFQlRfTUROKlVHRFMpCnNjX3RpbWUKCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoc2hpbnkpCnVpIDwtIGZsdWlkUGFnZSgKICB0aXRsZVBhbmVsKCJJIGxvdmUgR3JhcGhzIGFib3V0IFN0dWRlbnQgRGVidCIpLAogICMgc2VsZWN0SW5wdXQoJ3llYXInLAogICMgJ1llYXInLAogICMgY2hvaWNlcz1jKDIwMTAsMjAxMSwyMDEyLDIwMTMsMjAxNCwyMDE1LDIwMTYsMjAxNywyMDE4LDIwMTkpKSwgCiAgc2xpZGVySW5wdXQoaW5wdXRJZCA9ICJ5ZWFyIiwKICBsYWJlbCA9ICJZZWFyIiwKICB2YWx1ZSA9IGMoMjAxMCwyMDExLDIwMTIsMjAxMywyMDE0LDIwMTUsMjAxNiwyMDE3LDIwMTgsMjAxOSkpLAogIGxlYWZsZXRPdXRwdXQoInN0dWRlbnRkZWJ0bWFwIikKCikKCnNlcnZlciA8LSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBzZXNzaW9uKXsKICAjIFJlbmRlciBwbG90IG9mIHRvcCAxMCBtb3N0IHBvcHVsYXIgbmFtZXMKICAgIHNjX3RpbWVfc2VsZWN0aXZlIDwtIHJlYWN0aXZlKHtzY190aW1lICU+JSBzdWJzZXQoWWVhcl9FbmRpbmcgPT0gaW5wdXQkeWVhcikgJT4lIAogICAgICAgIGdyb3VwX2J5KFNUQUJCUikgJT4lIG11dGF0ZShgQXZlcmFnZSBTdHVkZW50IExvYW5zYD1zdW0oREVCVF9NRE5fU1RVREVOVCxuYS5ybT1UUlVFKS9zdW0oVUdEUyxuYS5ybT1UUlVFKSkgJT4lCiAgICAgICAgZ3JvdXBfYnkoU1RBQkJSLGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSAlPiUgc3VtbWFyaXplKCl9KQogICAgbGlicmFyeSh0aWdyaXMpCiAgICBzdGF0ZXMgPC0gc3RhdGVzKGNiID0gVFJVRSkKICAgIHN0YXRlc195ZWFyIDwtIHJlYWN0aXZlKHtzdGF0ZXMgJT4lIGlubmVyX2pvaW4oc2NfdGltZV9zZWxlY3RpdmUoKSwgYnk9YyhTVFVTUFM9J1NUQUJCUicpKX0pIAogICAgCiAgb3V0cHV0JHN0dWRlbnRkZWJ0bWFwIDwtIHJlbmRlckxlYWZsZXQoewogICAgcGFsID0gY29sb3JGYWN0b3IoJ0dyZWVucycsIGRvbWFpbiA9IHN0YXRlc195ZWFyKCkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApCiAgICBwb3BfcG9wIDwtIHBhc3RlKCJTdGF0ZToiLHN0YXRlc195ZWFyKCkkTkFNRSwiPGJyLz4iLAogICAgICAgICAgICAgICAgICAgICAiQXZlcmFnZSBTdHVkZW50IExvYW5zIiwiPGJyLz4iLCAib2YgU2Nob29scyBMb2NhdGVkIGluIFN0YXRlOiIsCiAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCckJyxyb3VuZChzdGF0ZXNfeWVhcigpJGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpCiAgICAKICAgIHNjX3RpbWVfc2VsZWN0aXZlX3RpdGxlIDwtIHRhZ3MkcCh0YWdzJHN0eWxlKCdwe2NvbG9yOmdyYXk7IGZvbnQtc2l6ZTogMTRweDsgZmFtaWx5OiBzZXJpZn0nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3MkYignQXZlcmFnZSBEZWJ0IEJ5IFN0YXRlICgyMDE5KScpKQogICAgbGVhZmxldChzdGF0ZXNfeWVhcigpKSAlPiUgYWRkUHJvdmlkZXJUaWxlcygiQ2FydG9EQi5Qb3NpdHJvbiIpICU+JQogICAgICBhZGRQb2x5Z29ucyhmaWxsQ29sb3IgPSB+cGFsKHN0YXRlc195ZWFyKCkkYEF2ZXJhZ2UgU3R1ZGVudCBMb2Fuc2ApLAogICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgIHdlaWdodCA9IDAuNSwKICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjcsICAKICAgICAgICAgICAgICBoaWdobGlnaHQgPSBoaWdobGlnaHRPcHRpb25zKAogICAgICAgICAgICAgICAgd2VpZ2h0ID0gNSwKICAgICAgICAgICAgICAgIGNvbG9yID0gIiM2NjYiLAogICAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjcsCiAgICAgICAgICAgICAgICBicmluZ1RvRnJvbnQgPSBUUlVFLAogICAgICAgICAgICAgICAgKSxwb3B1cD1wb3BfcG9wKSAlPiUgYWRkTGVnZW5kKHBvc2l0aW9uID0gImJvdHRvbWxlZnQiLCBjb2xvcnMgPWMoIiNFREY4RTkiLCIjQkFFNEIzIiwiIzc0QzQ3NiIsIiMzMUEzNTQiLCIjMDA2RDJDIiksIAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKHBhc3RlKCckJyxyb3VuZChtaW4oc3RhdGVzX3llYXIoKSRgQXZlcmFnZSBTdHVkZW50IExvYW5zYCkpKSwiICIsIiAiLCIgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJyQnLHJvdW5kKG1heChzdGF0ZXNfeWVhcigpJGBBdmVyYWdlIFN0dWRlbnQgTG9hbnNgKSkpKSwKICAgICAgICAgICAgdGl0bGUgPSAiQXZlcmFnZSBTdHVkZW50IExvYW5zIChQZXIgU3R1ZGVudCkiKSAlPiUKICBsZWFmbGV0OjpzZXRWaWV3KC05OC41Nzk1LCAzOS44MjgyLCB6b29tPTMpICU+JSBhZGRDb250cm9sKHNjX3RpbWVfc2VsZWN0aXZlX3RpdGxlLCBwb3NpdGlvbj0ndG9wcmlnaHQnKQogICAgfSkKICAgIG9ic2VydmUoewogICAgbGVhZmxldFByb3h5KCJzdHVkZW50ZGVidG1hcCIsIGRhdGEgPSBzdGF0ZXNfeWVhcigpKQogIH0pIAp9CgpzaGlueUFwcCh1aSA9IHVpLCBzZXJ2ZXIgPSBzZXJ2ZXIpCgpgYGAKCk5vdCBhbGwgc2Nob29scyBoYXZlIHNpbWlsYXIgYW1vdW50cyBvZiBtZWRpYW4gc3R1ZGVudCBkZWJ0IGJ1cmRlbiAoaS5lLiwgdXBvbiB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZXBheW1lbnQgcGVyaW9kKS4gVGhpcyBtYXAgc3VtbWFyaXplcyB0aGUgbWVkaWFuIGRlYnQgYnVyZGVuIGJ5IHRoZSBzdGF0ZSB0aGF0IHRoZSBzY2hvb2wgaXMgbG9jYXRlZCBpbi4gQXMgc2hvd24gaW4gdGhpcyBwbG90LCBzb21lIHN0YXRlcyAoaW5jbHVkaW5nIHNjaG9vbHMgaW4gUGVubnN5bHZhbmlhLCBNaW5uZXNvdGEsIElsbGlub2lzLCBldGMuKSB0ZW5kIHRvIGhhdmUgdGhlIGhpZ2hlc3QgYXZlcmFnZSBtZWRpYW4gZGVidCBidXJkZW4gYmV0d2VlbiB0aGUgc2Nob29scyB3aXRoaW4uIFRoZXNlIHN0YXRlcyBkbyBub3QgbmVjZXNzYXJpbHkgaG91c2UgdGhlIG1vc3QgcHJlc3RpZ2lvdXMgc2Nob29scy4gT25lIG9mIHRoZSB0aGluZ3Mgd2UgY2FuIHNlZSB3aGVuIGRpc2FnZ3JlZ2F0aW5nIHRoaXMgd2F5IGlzIHRoYXQgbG9jYXRpb25hbGx5IHRoZXJlIGlzIGEgbG90IG9mIGRpdmVyc2l0eSBvZiB0aGUgc3R1ZGVudCBsb2FuIGJ1cmRlbiAob24gYXZlcmFnZSkgZ2l2ZW4gdG8gc3R1ZGVudHMgYnkgc2Nob29scyB3aGVuIGRpc2FnZ3JlZ2F0ZWQgYXQgdGhlIHN0YXRlIGxldmVsIChyYW5naW5nIGZyb20gNEsgdG8gMThLIFVTRCBpbiAyMDE5KQpOb3RlIHRoYXQgd2UgaGF2ZSBhbHNvIGluY2x1ZGVkIHRoZSBzaGlueSBpbnRlcmFjdGl2aXR5IGNvbXBvbmVudCBpbiB3aGljaCBvbmUgY2FuIHNlbGVjdCB0aGUgeWVhciBvbiB0aGUgc2xpZGVyIHRvIHNlZSB0aGUgc3RhdGUtbGV2ZWwgZGVidCBtZWRpYW4gZGlzYWdncmVnYXRpb24gYWNyb3NzIHRoZSB5ZWFyczsgdGhpcyBpcyBub3QgdGhlIHByaW1hcnkgZnVuY3Rpb24gYnV0IGluc3RlYWQgaXMgYSBmdW5jdGlvbmFsaXR5IHdlIGFkZGVkIHRvIGFsbG93IGluZGl2aWR1YWxzIHRvICdleHBsb3JlIHRoZSBkYXRhJyBhIGJpdC4gCgpgYGB7cn0KdWkgPC0gZmx1aWRQYWdlKAogIHRpdGxlUGFuZWwoJ1RoZSBDb3N0IG9mIEhpZ2hlciBFZHVjYXRpb246IEFuIEV4cGxvcmF0aW9uIG9mIFN0dWRlbnQgRGVidCBpbiBBbWVyaWNhbiBVbml2ZXJzaXRpZXMnKQogIAopCiAKYGBgCgo=
>>>>>>> Stashed changes